# 2.11BSD#431 - /usr/src/local/mtools/init.c

##### Functions

    fix_mcwd          X
    init              X

##### Variables

    disk_offset       X
    fat_bits          X
    num_clus          X
    num_fat           X

##### Macros

    DWORD             X
    FULL_CYL          X
    WORD              X

       1: /*
       2:  * Initialize an MSDOS diskette.  Read the boot sector, and switch to the
       3:  * proper floppy disk device to match the format on the disk.  Sets a bunch
       4:  * of global variables.  Returns 0 on success, or 1 on failure.
       5:  */
       6:
       7: #include <stdio.h>
       8: #include <ctype.h>
       9: #include <sys/types.h>
      10: #include <sys/stat.h>
      11: #include "msdos.h"
      12:
      13: #define FULL_CYL
      14: #define WORD(x) ((boot->x)[0] + ((boot->x)[1] << 8))
      15: #define DWORD(x) ((boot->x)[0] + ((boot->x)[1] << 8) + ((boot->x)[2] << 16) + ((boot->x)[3] << 24))
      16:
      17: unsigned int num_clus;          /* total number of cluster */
      18: int num_fat;                /* the number of FAT tables */
      19: long disk_offset;           /* skip this many bytes */
      20: int fat_bits;               /* the FAT encoding scheme */
      21:
      22: extern int fd, fat_len, dir_len, dir_start, clus_size, dir_dirty, disk_dirty;
      23: extern int fat_error, disk_size;
      24: extern long disk_current;
      25: extern char *mcwd;
      26: extern unsigned char *fat_buf, *disk_buf, *dir_buf;
      27: extern struct device devices[];
      28: static struct bootsector *read_boot();
      29:
      30: int
      31: init(drive, mode)
      32: char drive;
      33: int mode;
      34: {
      35:     int fat_start, tracks, heads, sectors, old_dos;
      36:     char *malloc(), *name, *expand();
      37:     void perror(), exit(), reset_chain(), free(), fat_read();
      38:     struct bootsector *boot;
      39:     struct device *dev;
      40:
      41:     if (fd != -1) {
      42:         close(fd);
      43:         free((char *) fat_buf);
      44:         free((char *) disk_buf);
      45:         free((char *) dir_buf);
      46:     }
      47:                     /* check out the drive letter */
      48:     dev = devices;
      49:     while (dev->drive) {
      50:         if (dev->drive == drive)
      51:             break;
      52:         dev++;
      53:     }
      54:     if (!dev->drive) {
      55:         fprintf(stderr, "Drive '%c:' not supported\n", drive);
      56:         return(1);
      57:     }
      58:                     /* open the device */
      59:     while (dev->name) {
      60:         if (dev->drive != drive)
      61:             break;
      62:
      63:         name = expand(dev->name);
      64:         if ((fd = open(name, mode | dev->mode)) < 0) {
      65:             perror("init: open");
      66:             exit(1);
      67:         }
      68:                     /* set default parameters, if needed */
      69:         if (dev->gioctl) {
      70:             if ((*(dev->gioctl)) (fd, dev->tracks, dev->heads, dev->sectors))
      71:                 goto try_again;
      72:         }
      73:                     /* read the boot sector */
      74:         disk_offset = dev->offset;
      75:         if ((boot = read_boot()) == NULL)
      76:             goto try_again;
      77:
      78:         heads = WORD(nheads);
      79:         sectors = WORD(nsect);
      80:         if (heads && sectors)
      81:             tracks = WORD(psect) / (unsigned) (heads * sectors);
      82:
      83:                     /* sanity checking */
      84:         old_dos = 0;
      85:         if (!heads || heads > 100 || !sectors || sectors > 500 || tracks > 5000 || !boot->clsiz) {
      86:             /*
      87: 			 * The above technique will fail on diskettes that
      88: 			 * have been formatted with very old MSDOS, so we
      89: 			 * resort to the old table-driven method using the
      90: 			 * media signature (first byte in FAT).
      91: 			 */
      92:             unsigned char temp[MSECTOR_SIZE];
      93:             if (read(fd, (char *) temp, MSECTOR_SIZE) != MSECTOR_SIZE)
      94:                 temp[0] = '0';
      95:
      96:             switch (temp[0]) {
      97:                 case 0xfe:  /* 160k */
      98:                     tracks = 40;
      99:                     sectors = 8;
     100:                     heads = 1;
     101:                     dir_start = 3;
     102:                     dir_len = 4;
     103:                     clus_size = 1;
     104:                     fat_len = 1;
     105:                     num_clus = 313;
     106:                     break;
     107:                 case 0xfc:  /* 180k */
     108:                     tracks = 40;
     109:                     sectors = 9;
     110:                     heads = 1;
     111:                     dir_start = 5;
     112:                     dir_len = 4;
     113:                     clus_size = 1;
     114:                     fat_len = 2;
     115:                     num_clus = 351;
     116:                     break;
     117:                 case 0xff:  /* 320k */
     118:                     tracks = 40;
     119:                     sectors = 8;
     120:                     heads = 2;
     121:                     dir_start = 3;
     122:                     dir_len = 7;
     123:                     clus_size = 2;
     124:                     fat_len = 1;
     125:                     num_clus = 315;
     126:                     break;
     127:                 case 0xfd:  /* 360k */
     128:                     tracks = 40;
     129:                     sectors = 9;
     130:                     heads = 2;
     131:                     dir_start = 5;
     132:                     dir_len = 7;
     133:                     clus_size = 2;
     134:                     fat_len = 2;
     135:                     num_clus = 354;
     136:                     break;
     137:                 default:
     138:                     fprintf(stderr, "Probable non-MSDOS disk\n");
     139:                     close(fd);
     140:                     fd = -1;
     141:                     return(1);
     142:             }
     143:             fat_start = 1;
     144:             num_fat = 2;
     145:             old_dos = 1;
     146:         }
     147:                     /* check the parameters */
     148:         if (dev->tracks && !dev->gioctl) {
     149:             if (dev->tracks == tracks && dev->heads == heads && dev->sectors == sectors)
     150:                 break;
     151:         }
     152:         else
     153:             break;
     154:
     155: try_again:  close(fd);
     156:         fd = -1;
     157:         dev++;
     158:     }
     159:     if (fd == -1) {
     160:         if (boot != NULL && dev->tracks)
     161:             fprintf(stderr, "No support for %d tracks, %d heads, %d sector diskettes\n", tracks, heads, sectors);
     162:         return(1);
     163:     }
     164:                     /* set new parameters, if needed */
     165:     if (dev->gioctl) {
     166:         if ((*(dev->gioctl)) (fd, tracks, heads, sectors)) {
     167:             fprintf(stderr, "Can't set disk parameters\n");
     168:             close(fd);
     169:             fd = -1;
     170:             return(1);
     171:         }
     172:     }
     173:
     174:     /*
     175: 	 * all numbers are in sectors, except num_clus (which is in clusters)
     176: 	 */
     177:     if (!old_dos) {
     178:         clus_size = boot->clsiz;
     179:         fat_start = WORD(nrsvsect);
     180:         fat_len = WORD(fatlen);
     181:         dir_start = fat_start + (boot->nfat * fat_len);
     182:         dir_len = WORD(dirents) * MDIR_SIZE / (unsigned) MSECTOR_SIZE;
     183:         /*
     184: 		 * For DOS partitions > 32M
     185: 		 */
     186:         if (WORD(psect) == 0)
     187:             num_clus = (unsigned int) (DWORD(bigsect) - dir_start - dir_len) / clus_size;
     188:         else
     189:             num_clus = (unsigned int) (WORD(psect) - dir_start - dir_len) / clus_size;
     190:         num_fat = boot->nfat;
     191:     }
     192:                     /* more sanity checking */
     193:     if (clus_size * MSECTOR_SIZE > MAX_CLUSTER) {
     194:         fprintf(stderr, "Cluster size of %d is larger than max of %d\n", clus_size * MSECTOR_SIZE, MAX_CLUSTER);
     195:         close(fd);
     196:         fd = -1;
     197:         return(1);
     198:     }
     199:     if (!old_dos && WORD(secsiz) != MSECTOR_SIZE) {
     200:         fprintf(stderr, "Sector size of %d is not supported\n", WORD(secsiz));
     201:         close(fd);
     202:         fd = -1;
     203:         return(1);
     204:     }
     205:                     /* full cylinder buffering */
     206: #ifdef FULL_CYL
     207:     disk_size = (dev->tracks) ? (sectors * heads) : 1;
     208: #else /* FULL_CYL */
     209:     disk_size = (dev->tracks) ? sectors : 1;
     210: #endif /* FULL_CYL */
     211:
     212: /*
     213:  * The driver in Dell's SVR4 v2.01 is unreliable with large writes.
     214:  */
     215: #ifdef DELL
     216:     disk_size = 1;
     217: #endif /* DELL */
     218:
     219:     disk_buf = (unsigned char *) malloc((unsigned int) disk_size * MSECTOR_SIZE);
     220:     if (disk_buf == NULL) {
     221:         perror("init: malloc");
     222:         exit(1);
     223:     }
     224:                     /* read the FAT sectors */
     225:     disk_current = -1000L;
     226:     disk_dirty = 0;
     227:     fat_error = 0;
     228:     fat_bits = dev->fat_bits;
     229:     fat_read(fat_start);
     230:                     /* set dir_chain[] to root directory */
     231:     dir_dirty = 0;
     232:     reset_chain(NEW);
     233:     return(0);
     234: }
     235:
     236: /*
     237:  * Fix the info in the MCWD file to be a proper directory name.  Always
     238:  * has a leading separator.  Never has a trailing separator (unless it is
     239:  * the path itself).
     240:  */
     241:
     242: char *
     243: fix_mcwd()
     244: {
     245:     FILE *fp;
     246:     struct stat sbuf;
     247:     char *s, *strcpy(), *strcat(), *mcwd_path, *getenv(), *strncpy();
     248:     char buf[BUFSIZ], *file, *expand();
     249:     static char ans[MAX_PATH];
     250:     long now, time();
     251:
     252:     mcwd_path = getenv("MCWD");
     253:     if (mcwd_path == NULL || *mcwd_path == '\0')
     254:         mcwd_path = "$HOME/.mcwd";
     255:
     256:     file = expand(mcwd_path);
     257:     if (stat(file, &sbuf) < 0)
     258:         return("A:/");
     259:     /*
     260: 	 * Ignore the info, if the file is more than 6 hours old
     261: 	 */
     262:     time(&now);
     263:     if (now - sbuf.st_mtime > 6 * 60 * 60) {
     264:         fprintf(stderr, "Warning: \"%s\" is out of date, contents ignored\n", file);
     265:         return("A:/");
     266:     }
     267:
     268:     if (!(fp = fopen(file, "r")))
     269:         return("A:/");
     270:
     271:     if (!fgets(buf, BUFSIZ, fp))
     272:         return("A:/");
     273:
     274:     buf[strlen(buf) -1] = '\0';
     275:     fclose(fp);
     276:                     /* drive letter present? */
     277:     s = buf;
     278:     if (buf[0] && buf[1] == ':') {
     279:         strncpy(ans, buf, 2);
     280:         ans[2] = '\0';
     281:         s = &buf[2];
     282:     }
     283:     else
     284:         strcpy(ans, "A:");
     285:                     /* add a leading separator */
     286:     if (*s != '/' && *s != '\\') {
     287:         strcat(ans, "/");
     288:         strcat(ans, s);
     289:     }
     290:     else
     291:         strcat(ans, s);
     292:                     /* translate to upper case */
     293:     for (s = ans; *s; ++s) {
     294:         if (islower(*s))
     295:             *s = toupper(*s);
     296:         if (*s == '\\')
     297:             *s = '/';
     298:     }
     299:                     /* if only drive, colon, & separator */
     300:     if (strlen(ans) == 3)
     301:         return(ans);
     302:                     /* zap the trailing separator */
     303:     if (*--s == '/')
     304:         *s = '\0';
     305:     return(ans);
     306: }
     307:
     308: /*
     309:  * Read the boot sector.  We glean the disk parameters from this sector.
     310:  */
     311:
     312: static struct bootsector *
     313: read_boot()
     314: {
     315:     long lseek();
     316:     static struct bootsector boot;
     317:
     318:     if (lseek(fd, disk_offset, 0) < 0)
     319:         return(NULL);
     320:                     /* read the first sector */
     321:     if (read(fd, (char *) &boot, MSECTOR_SIZE) != MSECTOR_SIZE)
     322:         return(NULL);
     323:
     324:     return(&boot);
     325: }

#### Defined functions

fix_mcwd defined in line 242; used 22 times

- in /usr/src/local/mtools/mattrib.c line 34, 90
- in /usr/src/local/mtools/mcd.c line 28, 39
- in /usr/src/local/mtools/mdel.c line 33, 55
- in /usr/src/local/mtools/mdir.c line 32, 63
- in /usr/src/local/mtools/mlabel.c line 30, 52
- in /usr/src/local/mtools/mmd.c line 35, 62
- in /usr/src/local/mtools/mrd.c line 33, 48
- in /usr/src/local/mtools/mread.c line 49, 85
- in /usr/src/local/mtools/mren.c line 30, 48
- in /usr/src/local/mtools/mtype.c line 33, 61
- in /usr/src/local/mtools/mwrite.c line 43, 82

init defined in line 30; used 11 times

- in /usr/src/local/mtools/mattrib.c line 95
- in /usr/src/local/mtools/mcd.c line 49
- in /usr/src/local/mtools/mdel.c line 66
- in /usr/src/local/mtools/mdir.c line 85
- in /usr/src/local/mtools/mlabel.c line 58
- in /usr/src/local/mtools/mmd.c line 73
- in /usr/src/local/mtools/mrd.c line 59
- in /usr/src/local/mtools/mread.c line 103
- in /usr/src/local/mtools/mren.c line 51
- in /usr/src/local/mtools/mtype.c line 66
- in /usr/src/local/mtools/mwrite.c line 85

read_boot defined in line 312; used 2 times

- in line 28, 75

#### Defined variables

disk_offset defined in line 19; used 7 times

- in line 74, 318
- in /usr/src/local/mtools/buf_read.c line 32, 54
- in /usr/src/local/mtools/buf_write.c line 30, 60, 99

fat_bits defined in line 20; used 5 times

- in line 228(2)
- in /usr/src/local/mtools/fat_read.c line 23, 93
- in /usr/src/local/mtools/fat_write.c line 19

num_clus defined in line 17; used 7 times

- in line 105, 115, 125, 135, 187-189(2)
- in /usr/src/local/mtools/dir_make.c line 84

num_fat defined in line 18; used 4 times

- in line 144, 190
- in /usr/src/local/mtools/fat_write.c line 79, 88

#### Defined macros

DWORD defined in line 15; used 1 times

- in line 187

FULL_CYL defined in line 13; used 1 times

- in line 206

WORD defined in line 14; used 10 times

- in line 78-81(3), 179-189(5), 199-200(2)

Last modified: 1992-06-24 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 975 |