1: #define COMPAT 2: 3: /* 4: * Copyright (c) 1983 Regents of the University of California. 5: * All rights reserved. The Berkeley software License Agreement 6: * specifies the terms and conditions for redistribution. 7: */ 8: 9: #if !defined(lint) && defined(DOSCCS) 10: char copyright[] = 11: "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 12: All rights reserved.\n"; 13: 14: static char sccsid[] = "@(#)newfs.c 6.3 (2.11BSD) 1996/11/16"; 15: #endif 16: 17: /* 18: * newfs: friendly front end to mkfs 19: * 20: * The installation of bootblocks has been moved to 'disklabel(8)'. This 21: * program expects to find a disklabel present which will contain the 22: * geometry and partition size information. If 'newfs' is being run on 23: * a system without disklabels implemented in the kernel you must specify 24: * "-T diskname" (where 'diskname' is an entry in /etc/disktab). 25: */ 26: 27: #include <stdio.h> 28: #include <sys/param.h> 29: #include <sys/stat.h> 30: #include <sys/ioctl.h> 31: #include <sys/disklabel.h> 32: #include <sys/disk.h> 33: #include <sys/file.h> 34: 35: #include <ctype.h> 36: #include <errno.h> 37: #include <paths.h> 38: #include <stdlib.h> 39: #include <syslog.h> 40: #include <varargs.h> 41: 42: #ifdef COMPAT 43: char *disktype; 44: int unlabeled; 45: #endif 46: int Nflag; 47: struct disklabel *getdisklabel(); 48: 49: extern char *__progname; 50: 51: main(argc, argv) 52: int argc; 53: char **argv; 54: { 55: register struct disklabel *lp; 56: register struct partition *pp; 57: char *cp; 58: struct stat st; 59: long fssize, ltmp; 60: int f_n = 0, f_m = 0; 61: u_int f_i = 4096; 62: int ch, status, logsec; 63: int fsi; 64: char device[MAXPATHLEN], cmd[BUFSIZ], *index(), *rindex(); 65: char *special; 66: 67: while ((ch = getopt(argc,argv,"T:Nvm:s:n:i:")) != EOF) 68: switch((char)ch) { 69: case 'N': 70: case 'v': 71: Nflag = 1; 72: break; 73: #ifdef COMPAT 74: case 'T': 75: disktype = optarg; 76: break; 77: #endif 78: case 'm': 79: ltmp = atol(optarg); 80: if (ltmp <= 0 || ltmp > 32) 81: fatal("%s: out of 1 - 32 range", optarg); 82: f_m = (int)ltmp; 83: break; 84: case 'n': 85: ltmp = atol(optarg); 86: /* 87: * If the upper bound is changed here then mkfs.c must also be changed 88: * also else mkfs will cap the value to its limit. 89: */ 90: if (ltmp <= 0 || ltmp > 500) 91: fatal("%s: out of 1 - 500 range", optarg); 92: f_n = (int)ltmp; 93: break; 94: case 'i': 95: ltmp = atol(optarg); 96: if (ltmp < 512 || ltmp > 65536L) 97: fatal("%s: out of 512 - 65536 range", optarg); 98: f_i = (u_int)ltmp; 99: break; 100: case 's': 101: fssize = atol(optarg); 102: if (fssize <= 0) 103: fatal("%s: bad file system size", optarg); 104: break; 105: case '?': 106: default: 107: usage(); 108: } 109: 110: argc -= optind; 111: argv += optind; 112: if (argc != 2 && argc != 1) 113: usage(); 114: 115: /* figure out device name */ 116: special = argv[0]; 117: cp = rindex(special, '/'); 118: if (cp == 0) { 119: /* 120: * No path prefix; try /dev/r%s then /dev/%s 121: */ 122: (void)sprintf(device, "%s/r%s", _PATH_DEV, special); 123: if (stat(device, &st) == -1) 124: (void)sprintf(device, "%s/%s", _PATH_DEV, special); 125: special = device; 126: } 127: 128: fsi = open(special, O_RDONLY); 129: if (fsi < 0) 130: fatal("%s: %s", special, strerror(errno)); 131: 132: /* see if it exists and of a legal type */ 133: if (fstat(fsi, &st) == -1) 134: fatal("%s: %s", special, strerror(errno)); 135: if ((st.st_mode & S_IFMT) != S_IFCHR) 136: fatal("%s: not a character device", special); 137: cp = index(argv[0], '\0') - 1; 138: if (cp == 0 || (*cp < 'a' || *cp > 'h') && !isdigit(*cp)) 139: fatal("%s: can't figure out file system partition", argv[0]); 140: 141: #ifdef COMPAT 142: if (disktype == NULL) 143: disktype = argv[1]; 144: #endif 145: lp = getdisklabel(special, fsi); 146: if (isdigit(*cp)) 147: pp = &lp->d_partitions[0]; 148: else 149: pp = &lp->d_partitions[*cp - 'a']; 150: if (pp->p_size <= 0) 151: fatal("%s: '%c' partition is unavailable", argv[0], *cp); 152: #ifdef nothere 153: if (pp->p_fstype == FS_BOOT) 154: fatal("%s: '%c' partition overlaps boot program",argv[0], *cp); 155: #endif 156: 157: if (fssize == 0) 158: fssize = pp->p_size; 159: if (fssize > pp->p_size) 160: fatal("%s: maximum file system size on '%c' partition is %ld", 161: argv[0], *cp, pp->p_size); 162: /* 163: * Convert from sectors to logical blocks. Note that sector size 164: * must evenly devide DEV_BSIZE!!!!! 165: */ 166: 167: /* 168: * getdisklabel(3) forces the sector size to 512 because any other 169: * choice would wreck havoc in the disklabel(8) program and result 170: * in corrupted/destroyed filesystems. DEV_BSIZE had better be 171: * 1024! 172: */ 173: if (lp->d_secsize != 512) 174: fatal("%s: sector size not 512", argv[0]); 175: logsec = DEV_BSIZE/lp->d_secsize; 176: fssize /= logsec; 177: 178: /* build command */ 179: if (f_m == 0) /* If never specified then use default of 2 */ 180: f_m = 2; 181: if (f_n == 0) /* If never specified then 1/2 the cyl size */ 182: f_n = lp->d_secpercyl / logsec; 183: 184: sprintf(cmd, "/sbin/mkfs -m %d -n %d -i %u -s %ld %s", f_m, f_n, f_i, 185: fssize, special); 186: printf("newfs: %s\n", cmd); 187: 188: close(fsi); 189: 190: if (Nflag) 191: exit(0); 192: 193: if (status = system(cmd)) 194: exit(status >> 8); 195: exit(0); 196: } 197: 198: #ifdef COMPAT 199: char lmsg[] = "%s: can't read disk label; disk type must be specified"; 200: #else 201: char lmsg[] = "%s: can't read disk label"; 202: #endif 203: 204: struct disklabel * 205: getdisklabel(s, fd) 206: char *s; 207: int fd; 208: { 209: static struct disklabel lab; 210: 211: if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { 212: #ifdef COMPAT 213: if (disktype) { 214: struct disklabel *lp, *getdiskbyname(); 215: 216: unlabeled++; 217: lp = getdiskbyname(disktype); 218: if (lp == NULL) 219: fatal("%s: unknown disk type", disktype); 220: return (lp); 221: } 222: #endif 223: warn("ioctl (GDINFO)"); 224: fatal(lmsg, s); 225: } 226: return (&lab); 227: } 228: 229: static 230: usage() 231: { 232: 233: fprintf(stderr,"usage: %s [-N] [-m freelist-gap] [-s filesystem size] ", 234: __progname); 235: fprintf(stderr, "[-i bytes/inode] [-n freelist-modulus] "); 236: #ifdef COMPAT 237: fputs("[-T disk-type] ", stderr); 238: #endif 239: fputs("special-device\n", stderr); 240: exit(1); 241: } 242: 243: /*VARARGS*/ 244: void 245: fatal(fmt, va_alist) 246: char *fmt; 247: va_dcl 248: { 249: va_list ap; 250: 251: va_start(ap); 252: 253: if (fcntl(fileno(stderr), F_GETFL) < 0) { 254: openlog(__progname, LOG_CONS, LOG_DAEMON); 255: vsyslog(LOG_ERR, fmt, ap); 256: closelog(); 257: } else { 258: vwarnx(fmt, ap); 259: } 260: va_end(ap); 261: exit(1); 262: /*NOTREACHED*/ 263: }