diff options
Diffstat (limited to 'diskdev_cmds/disklib')
-rw-r--r-- | diskdev_cmds/disklib/dkcksum.c | 77 | ||||
-rw-r--r-- | diskdev_cmds/disklib/dkdisklabel.c | 193 | ||||
-rw-r--r-- | diskdev_cmds/disklib/dkopen.c | 57 | ||||
-rw-r--r-- | diskdev_cmds/disklib/dkopen.h | 56 | ||||
-rw-r--r-- | diskdev_cmds/disklib/dksecsize.c | 75 | ||||
-rw-r--r-- | diskdev_cmds/disklib/pathnames.h | 63 | ||||
-rw-r--r-- | diskdev_cmds/disklib/preen.c | 392 | ||||
-rw-r--r-- | diskdev_cmds/disklib/vfslist.c | 112 |
8 files changed, 1025 insertions, 0 deletions
diff --git a/diskdev_cmds/disklib/dkcksum.c b/diskdev_cmds/disklib/dkcksum.c new file mode 100644 index 0000000..e275cb2 --- /dev/null +++ b/diskdev_cmds/disklib/dkcksum.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include <sys/types.h> + +#if defined (linux) && defined (__powerpc__) +#define __ppc__ +#endif + +#include <sys/disklabel.h> + +u_short +dkcksum(lp) + register struct disklabel *lp; +{ + register u_short *start, *end; + register u_short sum = 0; + + start = (u_short *)lp; + end = (u_short *)&lp->d_partitions[lp->d_npartitions]; + while (start < end) + sum ^= *start++; + return (sum); +} diff --git a/diskdev_cmds/disklib/dkdisklabel.c b/diskdev_cmds/disklib/dkdisklabel.c new file mode 100644 index 0000000..3fffce5 --- /dev/null +++ b/diskdev_cmds/disklib/dkdisklabel.c @@ -0,0 +1,193 @@ +/* Copyright 1999 Apple Computer, Inc. + * + * Generate a bsd disk label routine. + * Input: open file descriptor to the device node, and + * pointer to a disk label structure to fill in + * Return: errno status + * + * HISTORY + * + * 24 Feb 1999 D. Markarian at Apple + * Created. + */ + +#include <string.h> /* memset */ +#include <sys/types.h> /* sys/disklabel.h */ +#include <sys/param.h> /* NBPG */ + +#include <sys/disk.h> /* DKIOCGETBLOCKSIZE ioctl */ + +#include <sys/disklabel.h> /* struct disklabel */ + +u_short dkcksum __P((register struct disklabel *lp)); +int dkdisklabelregenerate __P((int fd, struct disklabel * lp, int newblksize)); + +/* + * The following two constants set the default block and fragment sizes. + * Both constants must be a power of 2 and meet the following constraints: + * MINBSIZE <= GENBLKSIZE <= MAXBSIZE + * sectorsize <= GENFRAGSIZE <= GENBLKSIZE + * GENBLKSIZE / GENFRAGSIZE <= 8 + */ +#define GENFRAGSIZE 1024 +#define GENBLKSIZE NBPG /* 4096 */ + +/* + * Cylinder groups may have up to many cylinders. The actual + * number used depends upon how much information can be stored + * on a single cylinder. The default is to use 16 cylinders + * per group. + */ +#define GENCPG 16 + +/* + * Interleave is physical sector interleave, set up by the + * formatter or controller when formatting. When interleaving is + * in use, logically adjacent sectors are not physically + * contiguous, but instead are separated by some number of + * sectors. It is specified as the ratio of physical sectors + * traversed per logical sector. Thus an interleave of 1:1 + * implies contiguous layout, while 2:1 implies that logical + * sector 0 is separated by one sector from logical sector 1. + */ +#define GENINTERLEAVE 1 + +/* + * Rotational speed; # of data sectors per track. + */ +#define GENRPM 3600 +#define GENNSECTORS 32 + +int dkdisklabel(int fd, struct disklabel * lp) +{ + return dkdisklabelregenerate(fd, lp, 0); +} + +int dkdisklabelregenerate(int fd, struct disklabel * lp, int newblksize) +{ + /* + * Generate a bsd-style disk label for the specified device node. + */ + + int blksize; + int error; + int index; + int64_t numblks; + + /* obtain the size of the media (in blocks) */ + if ( (error = ioctl(fd, DKIOCGETBLOCKCOUNT, &numblks)) < 0 ) + return(error); + + /* obtain the block size of the media */ + if ( (error = ioctl(fd, DKIOCGETBLOCKSIZE, &blksize)) < 0 ) + return(error); + + /* adjust the size of the media with newblksize should it be specified */ + if (newblksize) + { + numblks = ((numblks * blksize) / newblksize); + blksize = newblksize; + } + + /* + * clear the disk label structure and then fill in the appropriate fields; + * we comment out lines that are initializations to zero with //, since it + * is redundant work + */ + memset(lp, 0, sizeof(struct disklabel)); + + lp->d_magic = DISKMAGIC; /* the magic number */ +// lp->d_type = 0; /* drive type */ +// lp->d_subtype = 0; /* controller/d_type specific */ +// lp->d_typename[0] = 0; /* type name, e.g. "eagle" */ + /* + * d_packname contains the pack identifier and is returned when + * the disklabel is read off the disk or in-core copy. + * d_boot0 and d_boot1 are the (optional) names of the + * primary (block 0) and secondary (block 1-15) bootstraps + * as found in /usr/mdec. These are returned when using + * getdiskbyname(3) to retrieve the values from /etc/disktab. + */ +// lp->d_packname[0] = 0; /* pack identifier */ + + /* disk geometry: */ + lp->d_secsize = blksize; /* # of bytes per sector */ + lp->d_nsectors = GENNSECTORS; /* # of data sectors per track */ + /* # of tracks per cylinder */ + if (numblks < 8*32*1024) /* <=528.4 MB */ + lp->d_ntracks = 16; + else if (numblks < 16*32*1024) /* <=1.057 GB */ + lp->d_ntracks = 32; + else if (numblks < 32*32*1024) /* <=2.114 GB */ + lp->d_ntracks = 54; + else if (numblks < 64*32*1024) /* <=4.228 GB */ + lp->d_ntracks = 128; + else /* > 4.228 GB */ + lp->d_ntracks = 255; + /* # of data cylinders per unit */ + lp->d_ncylinders = numblks / lp->d_ntracks / lp->d_nsectors; + /* # of data sectors per cylinder */ + lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks; + lp->d_secperunit = numblks; /* # of data sectors per unit */ + /* + * Spares (bad sector replacements) below are not counted in + * d_nsectors or d_secpercyl. Spare sectors are assumed to + * be physical sectors which occupy space at the end of each + * track and/or cylinder. + */ +// lp->d_sparespertrack = 0; /* # of spare sectors per track */ +// lp->d_sparespercyl = 0; /* # of data sectors per unit */ + /* + * Alternate cylinders include maintenance, replacement, configuration + * description areas, etc. + */ +// lp->d_acylinders = 0; /* # of alt. cylinders per unit */ + + /* hardware characteristics: */ + /* + * d_interleave, d_trackskew and d_cylskew describe perturbations + * in the media format used to compensate for a slow controller. + * Interleave is physical sector interleave, set up by the + * formatter or controller when formatting. When interleaving is + * in use, logically adjacent sectors are not physically + * contiguous, but instead are separated by some number of + * sectors. It is specified as the ratio of physical sectors + * traversed per logical sector. Thus an interleave of 1:1 + * implies contiguous layout, while 2:1 implies that logical + * sector 0 is separated by one sector from logical sector 1. + * d_trackskew is the offset of sector 0 on track N relative to + * sector 0 on track N-1 on the same cylinder. Finally, d_cylskew + * is the offset of sector 0 on cylinder N relative to sector 0 + * on cylinder N-1. + */ + lp->d_rpm = GENRPM; /* rotational speed */ + lp->d_interleave = GENINTERLEAVE; /* hardware sector interleave */ +// lp->d_trackskew = 0; /* sector 0 skew, per track */ +// lp->d_cylskew = 0; /* sector 0 skew, per cylinder */ +// lp->d_headswitch = 0; /* head switch time, usec */ +// lp->d_trkseek = 0; /* track-to-track seek, usec */ +// lp->d_flags = 0; /* generic flags */ +// lp->d_drivedata[0-4] = 0; /* drive-type specific information */ +// lp->d_spare[0-4] = 0; /* reserved for future use */ + lp->d_magic2 = DISKMAGIC; /* the magic number (again) */ +// lp->d_checksum = 0; /* xor of data incl. partitions */ + + /* filesystem and partition information: */ + lp->d_npartitions = MAXPARTITIONS; /* number of partitions */ + + for (index = 0; index < MAXPARTITIONS; index++) + { + struct partition * pp = &(lp->d_partitions[index]); + pp->p_size = numblks; /* number of sectors */ +// pp->p_offset = 0; /* starting sector */ + pp->p_fsize = MAX(GENFRAGSIZE, blksize); /* fs fragment size */ + pp->p_fstype = FS_BSDFFS; /* fs type */ + pp->p_frag = MIN(8, GENBLKSIZE / pp->p_fsize);/* fs fragments/block */ + pp->p_cpg = GENCPG; /* fs cylinders/group */ + } + + /* compute a checksum on the resulting structure */ + lp->d_checksum = dkcksum(lp); + + return 0; /* success */ +} diff --git a/diskdev_cmds/disklib/dkopen.c b/diskdev_cmds/disklib/dkopen.c new file mode 100644 index 0000000..7a94561 --- /dev/null +++ b/diskdev_cmds/disklib/dkopen.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include "dkopen.h" + +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <unistd.h> + +int dkopen (const char *path, int flags, int mode) +{ +#if defined (linux) + return (open64 (path, flags, mode)); +#elif defined (__APPLE__) + return (open (path, flags, mode)); +#endif +} + +int dkclose (int filedes) +{ +#if defined (linux) + return (close (filedes)); +#elif defined (__APPLE__) + return (close (filedes)); +#endif +} + +off64_t dklseek (int filedes, off64_t offset, int whence) +{ +#if defined (linux) + return (lseek64 (filedes, offset, whence)); +#elif defined (__APPLE__) + return (lseek (filedes, offset, whence)); +#endif +} + diff --git a/diskdev_cmds/disklib/dkopen.h b/diskdev_cmds/disklib/dkopen.h new file mode 100644 index 0000000..eb0bdeb --- /dev/null +++ b/diskdev_cmds/disklib/dkopen.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * File I/O stubs + * + * Linux and other OSs may use open64, lseek64 instead of defaulting off_t to + * 64-bits like OSX does. This file provides cover functions to always perform + * 64-bit file I/O. + */ + +#ifndef _DKOPEN_H_ +#define _DKOPEN_H_ + +/* Must predefine the large file flags before including sys/types.h */ +#if defined (linux) +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#elif defined (__APPLE__) +#else +#error Platform not recognized +#endif + +#include <sys/types.h> + +/* Typedef off64_t for platforms that don't have it declared */ +#if defined (__APPLE__) && !defined (linux) +typedef u_int64_t off64_t; +#endif + +int dkopen (const char *path, int flags, int mode); +int dkclose (int filedes); + +off64_t dklseek (int fileds, off64_t offset, int whence); + +#endif diff --git a/diskdev_cmds/disklib/dksecsize.c b/diskdev_cmds/disklib/dksecsize.c new file mode 100644 index 0000000..0cfad82 --- /dev/null +++ b/diskdev_cmds/disklib/dksecsize.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* Copyright 1998 Apple Computer, Inc. + * + * Get disk label's sector size routine. + * Input: pointer to a block device string ie: "/dev/disk1s1" + * Return: sector size from the disk label + * + * HISTORY + * + * 27 May 1998 K. Crippes at Apple + * Rhapsody version created. + * 18 Feb 1999 D. Markarian at Apple + * DKIOCGLABEL deprecated; using DKIOCBLKSIZE instead, which now returns + * the appropriate size for ufs partitions created with wierd block sizes. + */ + +#include <sys/types.h> +#include <sys/file.h> +#include <sys/disk.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +char *blockcheck __P((char *)); + +long dksecsize (dev) + char *dev; +{ + int fd; /* file descriptor for reading device label */ + char *cdev; + int devblklen; + extern int errno; + + /* Convert block device into a character device string */ + if ((cdev = blockcheck(dev))) { + if ((fd = open(cdev, O_RDONLY)) < 0) { + fprintf(stderr, "Can't open %s, %s\n", cdev, strerror(errno)); + return (0); + } + } + else + return (0); + + if (ioctl(fd, DKIOCGETBLOCKSIZE, &devblklen) < 0) { + (void)close(fd); + return (0); + } + else { + (void)close(fd); + return (devblklen); + } +} + diff --git a/diskdev_cmds/disklib/pathnames.h b/diskdev_cmds/disklib/pathnames.h new file mode 100644 index 0000000..59cd945 --- /dev/null +++ b/diskdev_cmds/disklib/pathnames.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)pathnames.h 8.1 (Berkeley) 6/5/93 + */ + +#include <paths.h> + +#define _PATH_DTMP "/etc/dtmp" +#define _PATH_DUMPDATES "/etc/dumpdates" +#define _PATH_LOCK "/tmp/dumplockXXXXXX" +#define _PATH_RMT "rmt" diff --git a/diskdev_cmds/disklib/preen.c b/diskdev_cmds/disklib/preen.c new file mode 100644 index 0000000..f7128e0 --- /dev/null +++ b/diskdev_cmds/disklib/preen.c @@ -0,0 +1,392 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> + +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#include <ctype.h> +#include <fstab.h> +#include <string.h> +#include <TargetConditionals.h> + +#if TARGET_OS_OSX +struct part { + struct part *next; /* forward link of partitions on disk */ + char *name; /* device name */ + char *fsname; /* mounted filesystem name */ + long auxdata; /* auxillary data for application */ +} *badlist, **badnext = &badlist; + +struct disk { + char *name; /* disk base name */ + struct disk *next; /* forward link for list of disks */ + struct part *part; /* head of list of partitions on disk */ + int pid; /* If != 0, pid of proc working on */ +} *disks; + +int nrun, ndisks; +char hotroot; + +static void addpart (char *name, char *fsname, long auxdata); +static struct disk *finddisk (char *name); +static char *rawname (char *name); +static int startdisk (struct disk *dk, + int (*checkit)(char *, char *, long, int)); +static char *unrawname (char *name); +char* blockcheck (char *name); + +int +checkfstab(preen, maxrun, docheck, chkit) + int preen; + int maxrun; + int (*docheck)(struct fstab *); + int (*chkit)(char *, char *, long, int); +{ + register struct fstab *fsp; + register struct disk *dk, *nextdisk; + register struct part *pt; + int ret, pid, retcode, passno, sumstatus, status; + long auxdata; + char *name; + + sumstatus = 0; + for (passno = 1; passno <= 2; passno++) { + if (setfsent() == 0) { + fprintf(stderr, "Can't open checklist file: %s\n", + _PATH_FSTAB); + return (8); + } + while ((fsp = getfsent()) != 0) { + if ((auxdata = (*docheck)(fsp)) == 0) + continue; + if (preen == 0 || + (passno == 1 && fsp->fs_passno == 1)) { + if ((name = blockcheck(fsp->fs_spec)) != 0) { + if ((sumstatus = (*chkit)(name, + fsp->fs_file, auxdata, 0)) != 0) + return (sumstatus); + } else if (preen) + return (8); + } else if (passno == 2 && fsp->fs_passno > 1) { + if ((name = blockcheck(fsp->fs_spec)) == NULL) { + fprintf(stderr, "BAD DISK NAME %s\n", + fsp->fs_spec); + sumstatus |= 8; + continue; + } + addpart(name, fsp->fs_file, auxdata); + } + } + if (preen == 0) + return (0); + } + if (preen) { + if (maxrun == 0) + maxrun = ndisks; + if (maxrun > ndisks) + maxrun = ndisks; + nextdisk = disks; + for (passno = 0; passno < maxrun; ++passno) { + while ((ret = startdisk(nextdisk, chkit)) && nrun > 0) + sleep(10); + if (ret) + return (ret); + nextdisk = nextdisk->next; + } + while ((pid = wait(&status)) != -1) { + for (dk = disks; dk; dk = dk->next) + if (dk->pid == pid) + break; + if (dk == 0) { + printf("Unknown pid %d\n", pid); + continue; + } + if (WIFEXITED(status)) + retcode = WEXITSTATUS(status); + else + retcode = 0; + if (WIFSIGNALED(status)) { + printf("%s (%s): EXITED WITH SIGNAL %d\n", + dk->part->name, dk->part->fsname, + WTERMSIG(status)); + retcode = 8; + } + if (retcode != 0) { + sumstatus |= retcode; + *badnext = dk->part; + badnext = &dk->part->next; + dk->part = dk->part->next; + *badnext = NULL; + } else + dk->part = dk->part->next; + dk->pid = 0; + nrun--; + if (dk->part == NULL) + ndisks--; + + if (nextdisk == NULL) { + if (dk->part) { + while ((ret = startdisk(dk, chkit)) && + nrun > 0) + sleep(10); + if (ret) + return (ret); + } + } else if (nrun < maxrun && nrun < ndisks) { + for ( ;; ) { + if ((nextdisk = nextdisk->next) == NULL) + nextdisk = disks; + if (nextdisk->part != NULL && + nextdisk->pid == 0) + break; + } + while ((ret = startdisk(nextdisk, chkit)) && + nrun > 0) + sleep(10); + if (ret) + return (ret); + } + } + } + if (sumstatus) { + if (badlist == 0) + return (sumstatus); + fprintf(stderr, "THE FOLLOWING FILE SYSTEM%s HAD AN %s\n\t", + badlist->next ? "S" : "", "UNEXPECTED INCONSISTENCY:"); + for (pt = badlist; pt; pt = pt->next) + fprintf(stderr, "%s (%s)%s", pt->name, pt->fsname, + pt->next ? ", " : "\n"); + return (sumstatus); + } + (void)endfsent(); + return (0); +} + +static struct disk * +finddisk(name) + char *name; +{ + register struct disk *dk, **dkp; + register char *p; + size_t len; + + for (len = strlen(name), p = name + len - 1; p >= name; --p) + if (isdigit(*p)) { + len = p - name + 1; + break; + } + + for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) { + if (strncmp(dk->name, name, len) == 0 && + dk->name[len] == 0) + return (dk); + } + if ((*dkp = (struct disk *)malloc(sizeof(struct disk))) == NULL) { + fprintf(stderr, "out of memory"); + exit (8); + } + dk = *dkp; + if ((dk->name = malloc(len + 1)) == NULL) { + fprintf(stderr, "out of memory"); + exit (8); + } + (void)strncpy(dk->name, name, len); + dk->name[len] = '\0'; + dk->part = NULL; + dk->next = NULL; + dk->pid = 0; + ndisks++; + return (dk); +} + +static void +addpart(name, fsname, auxdata) + char *name, *fsname; + long auxdata; +{ + struct disk *dk = finddisk(name); + register struct part *pt, **ppt = &dk->part; + + for (pt = dk->part; pt; ppt = &pt->next, pt = pt->next) + if (strcmp(pt->name, name) == 0) { + printf("%s in fstab more than once!\n", name); + return; + } + if ((*ppt = (struct part *)malloc(sizeof(struct part))) == NULL) { + fprintf(stderr, "out of memory"); + exit (8); + } + pt = *ppt; + if ((pt->name = strdup(name)) == NULL) { + fprintf(stderr, "out of memory"); + exit (8); + } + if ((pt->fsname = strdup(fsname)) == NULL) { + fprintf(stderr, "out of memory"); + exit (8); + } + pt->next = NULL; + pt->auxdata = auxdata; +} + +static int +startdisk(dk, checkit) + register struct disk *dk; + int (*checkit)(char *, char *, long, int); +{ + register struct part *pt = dk->part; + + dk->pid = fork(); + if (dk->pid < 0) { + perror("fork"); + return (8); + } + if (dk->pid == 0) + exit((*checkit)(pt->name, pt->fsname, pt->auxdata, 1)); + nrun++; + return (0); +} + +char * +blockcheck(char* origname) { + struct stat stslash, stblock, stchar; + char *newname, *raw; + int retried = 0; + + hotroot = 0; + if (stat("/", &stslash) < 0) { + perror("/"); + printf("Can't stat root\n"); + return (origname); + } + newname = origname; +retry: + if (stat(newname, &stblock) < 0) { + perror(newname); + printf("Can't stat %s\n", newname); + return (origname); + } + if ((stblock.st_mode & S_IFMT) == S_IFBLK) { + if (stslash.st_dev == stblock.st_rdev) + hotroot++; + raw = rawname(newname); + if (stat(raw, &stchar) < 0) { + perror(raw); + printf("Can't stat %s\n", raw); + return (origname); + } + if ((stchar.st_mode & S_IFMT) == S_IFCHR) { + return (raw); + } else { + printf("%s is not a character device\n", raw); + return (origname); + } + } else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) { + newname = unrawname(newname); + retried++; + goto retry; + } + /* + * Not a block or character device, just return name and + * let the user decide whether to use it. + */ + return (origname); +} + +static char * +unrawname(name) + char *name; +{ + char *dp; + struct stat stb; + size_t dp_len; + + if ((dp = strrchr(name, '/')) == 0) + return (name); + if (stat(name, &stb) < 0) + return (name); + if ((stb.st_mode & S_IFMT) != S_IFCHR) + return (name); + if (dp[1] != 'r') + return (name); + dp_len = strlen(&dp[2]) + 1; + (void)memmove(&dp[1], &dp[2], dp_len); + return (name); +} + +static char * +rawname(name) + char *name; +{ + static char rawbuf[32]; + char *dp; + + if ((dp = strrchr(name, '/')) == 0) + return (0); + *dp = 0; + (void)strncpy(rawbuf, name, sizeof(rawbuf)); + *dp = '/'; + (void)strlcat(rawbuf, "/r", sizeof(rawbuf)); + (void)strlcat(rawbuf, &dp[1], sizeof(rawbuf)); + return (rawbuf); +} + +#endif /* TARGET_OS_OSX */ + diff --git a/diskdev_cmds/disklib/vfslist.c b/diskdev_cmds/disklib/vfslist.c new file mode 100644 index 0000000..6ecafcd --- /dev/null +++ b/diskdev_cmds/disklib/vfslist.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/*- + * Copyright (c) 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <err.h> + +int checkvfsname __P((const char *, const char **)); +const char **makevfslist __P((char *)); +static int skipvfs; + +int +checkvfsname(vfsname, vfslist) + const char *vfsname; + const char **vfslist; +{ + + if (vfslist == NULL) + return (0); + while (*vfslist != NULL) { + if (strcmp(vfsname, *vfslist) == 0) + return (skipvfs); + ++vfslist; + } + return (!skipvfs); +} + +const char ** +makevfslist(fslist) + char *fslist; +{ + const char **av; + int i; + char *nextcp; + + if (fslist == NULL) + return (NULL); + if (fslist[0] == 'n' && fslist[1] == 'o') { + fslist += 2; + skipvfs = 1; + } + for (i = 0, nextcp = fslist; *nextcp; nextcp++) + if (*nextcp == ',') + i++; + if ((av = malloc((size_t)(i + 2) * sizeof(char *))) == NULL) { + warn(NULL); + return (NULL); + } + nextcp = fslist; + i = 0; + av[i++] = nextcp; + while ((nextcp = strchr(nextcp, ',')) != NULL) { + *nextcp++ = '\0'; + av[i++] = nextcp; + } + av[i++] = NULL; + return (av); +} |