📄 disklabel.c
字号:
case ESRCH: fprintf(stderr, "No disk label on disk;\n"); fprintf(stderr, "use \"disklabel -r\" to install initial label\n"); break; case EINVAL: fprintf(stderr, "Label magic number or checksum is wrong!\n"); fprintf(stderr, "(disklabel or kernel is out of date?)\n"); break; case EBUSY: fprintf(stderr, "Open partition would move or shrink\n"); break; case EXDEV: fprintf(stderr, "Labeled partition or 'a' partition must start at beginning of disk\n"); break; default: errno = saverrno; perror((char *)NULL); break; }}/* * Fetch disklabel for disk. * Use ioctl to get label unless -r flag is given. */struct disklabel *readlabel(f) int f;{ register struct disklabel *lp; if (rflag) { if (read(f, bootarea, BBSIZE) < BBSIZE) Perror(specname); for (lp = (struct disklabel *)bootarea; lp <= (struct disklabel *)(bootarea + BBSIZE - sizeof(*lp)); lp = (struct disklabel *)((char *)lp + 16)) if (lp->d_magic == DISKMAGIC && lp->d_magic2 == DISKMAGIC) break; if (lp > (struct disklabel *)(bootarea+BBSIZE-sizeof(*lp)) || lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC || dkcksum(lp) != 0) { fprintf(stderr, "Bad pack magic number (label is damaged, or pack is unlabeled)\n"); /* lp = (struct disklabel *)(bootarea + LABELOFFSET); */ exit (1); } } else { lp = &lab; if (ioctl(f, DIOCGDINFO, lp) < 0) Perror("ioctl DIOCGDINFO"); } return (lp);}/* * Construct a bootarea (d_bbsize bytes) in the specified buffer ``boot'' * Returns a pointer to the disklabel portion of the bootarea. */struct disklabel *makebootarea(boot, dp, f) char *boot; register struct disklabel *dp; int f;{ struct disklabel *lp; register char *p; int b;#if NUMBOOT > 0 char *dkbasename; struct stat sb;#endif /* XXX */ if (dp->d_secsize == 0) { dp->d_secsize = DEV_BSIZE; dp->d_bbsize = BBSIZE; } lp = (struct disklabel *) (boot + (LABELSECTOR * dp->d_secsize) + LABELOFFSET); bzero((char *)lp, sizeof *lp);#if NUMBOOT > 0 /* * If we are not installing a boot program but we are installing a * label on disk then we must read the current bootarea so we don't * clobber the existing boot. */ if (!installboot) { if (rflag) { if (read(f, boot, BBSIZE) < BBSIZE) Perror(specname); bzero((char *)lp, sizeof *lp); } return (lp); } /* * We are installing a boot program. Determine the name(s) and * read them into the appropriate places in the boot area. */ if (!xxboot || !bootxx) { dkbasename = np; if ((p = rindex(dkname, '/')) == NULL) p = dkname; else p++; while (*p && !isdigit(*p)) *np++ = *p++; *np++ = '\0'; if (!xxboot) { (void)sprintf(np, "%s/%sboot", _PATH_BOOTDIR, dkbasename); if (access(np, F_OK) < 0 && dkbasename[0] == 'r') dkbasename++; xxboot = np; (void)sprintf(xxboot, "%s/%sboot", _PATH_BOOTDIR, dkbasename); np += strlen(xxboot) + 1; }#if NUMBOOT > 1 if (!bootxx) { (void)sprintf(np, "%s/boot%s", _PATH_BOOTDIR, dkbasename); if (access(np, F_OK) < 0 && dkbasename[0] == 'r') dkbasename++; bootxx = np; (void)sprintf(bootxx, "%s/boot%s", _PATH_BOOTDIR, dkbasename); np += strlen(bootxx) + 1; }#endif }#ifdef DEBUG if (debug) fprintf(stderr, "bootstraps: xxboot = %s, bootxx = %s\n", xxboot, bootxx ? bootxx : "NONE");#endif /* * Strange rules: * 1. One-piece bootstrap (hp300/hp800) * up to d_bbsize bytes of ``xxboot'' go in bootarea, the rest * is remembered and written later following the bootarea. * 2. Two-piece bootstraps (vax/i386?/mips?) * up to d_secsize bytes of ``xxboot'' go in first d_secsize * bytes of bootarea, remaining d_bbsize-d_secsize filled * from ``bootxx''. */ b = open(xxboot, O_RDONLY); if (b < 0) Perror(xxboot);#if NUMBOOT > 1 if (read(b, boot, (int)dp->d_secsize) < 0) Perror(xxboot); (void)close(b); b = open(bootxx, O_RDONLY); if (b < 0) Perror(bootxx); if (read(b, &boot[dp->d_secsize], (int)(dp->d_bbsize-dp->d_secsize)) < 0) Perror(bootxx);#else if (read(b, boot, (int)dp->d_bbsize) < 0) Perror(xxboot); (void)fstat(b, &sb); bootsize = (int)sb.st_size - dp->d_bbsize; if (bootsize > 0) { /* XXX assume d_secsize is a power of two */ bootsize = (bootsize + dp->d_secsize-1) & ~(dp->d_secsize-1); bootbuf = (char *)malloc((size_t)bootsize); if (bootbuf == 0) Perror(xxboot); if (read(b, bootbuf, bootsize) < 0) { free(bootbuf); Perror(xxboot); } }#endif (void)close(b);#endif /* * Make sure no part of the bootstrap is written in the area * reserved for the label. */ for (p = (char *)lp; p < (char *)lp + sizeof(struct disklabel); p++) if (*p) { fprintf(stderr, "Bootstrap doesn't leave room for disk label\n"); exit(2); } return (lp);}display(f, lp) FILE *f; register struct disklabel *lp;{ register int i, j; register struct partition *pp; fprintf(f, "# %s:\n", specname); if ((unsigned) lp->d_type < DKMAXTYPES) fprintf(f, "type: %s\n", dktypenames[lp->d_type]); else fprintf(f, "type: %d\n", lp->d_type); fprintf(f, "disk: %.*s\n", sizeof(lp->d_typename), lp->d_typename); fprintf(f, "label: %.*s\n", sizeof(lp->d_packname), lp->d_packname); fprintf(f, "flags:"); if (lp->d_flags & D_REMOVABLE) fprintf(f, " removeable"); if (lp->d_flags & D_ECC) fprintf(f, " ecc"); if (lp->d_flags & D_BADSECT) fprintf(f, " badsect"); fprintf(f, "\n"); fprintf(f, "bytes/sector: %d\n", lp->d_secsize); fprintf(f, "sectors/track: %d\n", lp->d_nsectors); fprintf(f, "tracks/cylinder: %d\n", lp->d_ntracks); fprintf(f, "sectors/cylinder: %d\n", lp->d_secpercyl); fprintf(f, "cylinders: %d\n", lp->d_ncylinders); fprintf(f, "rpm: %d\n", lp->d_rpm); fprintf(f, "interleave: %d\n", lp->d_interleave); fprintf(f, "trackskew: %d\n", lp->d_trackskew); fprintf(f, "cylinderskew: %d\n", lp->d_cylskew); fprintf(f, "headswitch: %d\t\t# milliseconds\n", lp->d_headswitch); fprintf(f, "track-to-track seek: %d\t# milliseconds\n", lp->d_trkseek); fprintf(f, "drivedata: "); for (i = NDDATA - 1; i >= 0; i--) if (lp->d_drivedata[i]) break; if (i < 0) i = 0; for (j = 0; j <= i; j++) fprintf(f, "%d ", lp->d_drivedata[j]); fprintf(f, "\n\n%d partitions:\n", lp->d_npartitions); fprintf(f, "# size offset fstype [fsize bsize cpg]\n"); pp = lp->d_partitions; for (i = 0; i < lp->d_npartitions; i++, pp++) { if (pp->p_size) { fprintf(f, " %c: %8d %8d ", 'a' + i, pp->p_size, pp->p_offset); if ((unsigned) pp->p_fstype < FSMAXTYPES) fprintf(f, "%8.8s", fstypenames[pp->p_fstype]); else fprintf(f, "%8d", pp->p_fstype); switch (pp->p_fstype) { case FS_UNUSED: /* XXX */ fprintf(f, " %5d %5d %5.5s ", pp->p_fsize, pp->p_fsize * pp->p_frag, ""); break; case FS_BSDFFS: fprintf(f, " %5d %5d %5d ", pp->p_fsize, pp->p_fsize * pp->p_frag, pp->p_cpg); break; default: fprintf(f, "%20.20s", ""); break; } fprintf(f, "\t# (Cyl. %4d", pp->p_offset / lp->d_secpercyl); if (pp->p_offset % lp->d_secpercyl) putc('*', f); else putc(' ', f); fprintf(f, "- %d", (pp->p_offset + pp->p_size + lp->d_secpercyl - 1) / lp->d_secpercyl - 1); if (pp->p_size % lp->d_secpercyl) putc('*', f); fprintf(f, ")\n"); } } fflush(f);}edit(lp, f) struct disklabel *lp; int f;{ register int c; struct disklabel label; FILE *fd; char *mktemp(); (void) mktemp(tmpfil); fd = fopen(tmpfil, "w"); if (fd == NULL) { fprintf(stderr, "%s: Can't create\n", tmpfil); return (1); } (void)fchmod(fileno(fd), 0600); display(fd, lp); fclose(fd); for (;;) { if (!editit()) break; fd = fopen(tmpfil, "r"); if (fd == NULL) { fprintf(stderr, "%s: Can't reopen for reading\n", tmpfil); break; } bzero((char *)&label, sizeof(label)); if (getasciilabel(fd, &label)) { *lp = label; if (writelabel(f, bootarea, lp) == 0) { (void) unlink(tmpfil); return (0); } } printf("re-edit the label? [y]: "); fflush(stdout); c = getchar(); if (c != EOF && c != (int)'\n') while (getchar() != (int)'\n') ; if (c == (int)'n') break; } (void) unlink(tmpfil); return (1);}editit(){ register int pid, xpid; int stat, omask; extern char *getenv(); omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP)); while ((pid = fork()) < 0) { extern int errno; if (errno == EPROCLIM) { fprintf(stderr, "You have too many processes\n"); return(0); } if (errno != EAGAIN) { perror("fork"); return(0); } sleep(1); } if (pid == 0) { register char *ed; sigsetmask(omask); setgid(getgid()); setuid(getuid()); if ((ed = getenv("EDITOR")) == (char *)0) ed = DEFEDITOR; execlp(ed, ed, tmpfil, 0); perror(ed); exit(1); } while ((xpid = wait(&stat)) >= 0) if (xpid == pid) break; sigsetmask(omask); return(!stat);}char *skip(cp) register char *cp;{ while (*cp != '\0' && isspace(*cp)) cp++; if (*cp == '\0' || *cp == '#') return ((char *)NULL); return (cp);}char *word(cp) register char *cp;{ register char c; while (*cp != '\0' && !isspace(*cp) && *cp != '#') cp++; if ((c = *cp) != '\0') { *cp++ = '\0'; if (c != '#') return (skip(cp)); } return ((char *)NULL);}/* * Read an ascii label in from fd f, * in the same format as that put out by display(), * and fill in lp. */getasciilabel(f, lp) FILE *f; register struct disklabel *lp;{ register char **cpp, *cp; register struct partition *pp; char *tp, *s, line[BUFSIZ]; int v, lineno = 0, errors = 0; lp->d_bbsize = BBSIZE; /* XXX */ lp->d_sbsize = SBSIZE; /* XXX */ while (fgets(line, sizeof(line) - 1, f)) { lineno++; if (cp = index(line,'\n')) *cp = '\0'; cp = skip(line); if (cp == NULL) continue; tp = index(cp, ':'); if (tp == NULL) { fprintf(stderr, "line %d: syntax error\n", lineno); errors++; continue; } *tp++ = '\0', tp = skip(tp); if (streq(cp, "type")) { if (tp == NULL) tp = "unknown"; cpp = dktypenames; for (; cpp < &dktypenames[DKMAXTYPES]; cpp++) if ((s = *cpp) && streq(s, tp)) { lp->d_type = cpp - dktypenames; goto next;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -