Annotation of coherent/d/bin/dos/dos2.c, revision 1.1.1.1

1.1       root        1: /*#define DEBUG 1*/
                      2: /* dos.c */
                      3: 
                      4: #include "dos0.h"
                      5: 
                      6: /*
                      7:  * Convert an MS-DOS filename and path
                      8:  * to a NUL-terminated COHERENT filename in cohfile[].
                      9:  * Return a pointer to the NUL terminator.
                     10:  */
                     11: char *
                     12: cohname(name, dp) register char *name; DIR *dp;
                     13: {
                     14:        register char *cp;
                     15: 
                     16:        if (dp == root)
                     17:                cp = cohfile;
                     18:        else {
                     19:                cp = cohname(dp->d_dname, dp->d_parent);
                     20:                *cp++ = '/';
                     21:                *cp = '\0';
                     22:        }
                     23:        cp = lcname(cp, name, 8);
                     24:        name += 8;
                     25:        if (*name != ' ') {
                     26:                *cp++ = '.';
                     27:                cp = lcname(cp, name, 3);
                     28:        }
                     29:        return cp;
                     30: }
                     31: 
                     32: /*
                     33:  * Change the COHERENT time of the given file to the MS-DOS time of mdp.
                     34:  * There should be a COHERENT function which converts struct tm to time_t,
                     35:  * but in the meantime this does it by hand.  What a pain.
                     36:  */
                     37: void
                     38: cohtime(file, mdp) char *file; MDIR *mdp;
                     39: {
                     40:        time_t cohtime, times[2];
                     41:        static short mdays[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
                     42: 
                     43:        settz();
                     44:        cohtime = ((10 * 365L) + 2);            /* days 1/1/70 to 1/1/80 */
                     45:        cohtime += (m_year(mdp) * 365L);        /* to 1/1/year */
                     46:        if (m_month(mdp) > 2)                   /* leap year adjust */
                     47:                cohtime += ((m_year(mdp)+4)/4);
                     48:        else
                     49:                cohtime += ((m_year(mdp)+3)/4);
                     50:        cohtime += mdays[m_month(mdp)-1];               /* to mon/1/year */
                     51:        cohtime += (m_day(mdp)-1);              /* to mon/day/year */
                     52:        cohtime *= 24L;                         /* hours */
                     53:        cohtime += m_hour(mdp);
                     54:        cohtime *= 60L;
                     55:        cohtime += m_min(mdp);                  /* minutes */
                     56:        cohtime *= 60L;
                     57:        cohtime += m_sec(mdp) * 2;              /* seconds */
                     58:        cohtime += timezone;
                     59:        times[0] = times[1] = cohtime;
                     60:        if (utime(file, times) == -1)
                     61:                fatal("cannot set time of file \"%s\"", file);
                     62: }
                     63: 
                     64: /*
                     65:  * Find or create an MS-DOS directory.
                     66:  * Return a pointer to the DIR.
                     67:  * Failure is always fatal.
                     68:  */
                     69: DIR *
                     70: creatdir(name) char *name;
                     71: {
                     72:        register MDIR *mdp;
                     73:        register char *cp;
                     74:        DIR *dp, *ndp;
                     75: 
                     76:        /* Check if directory exists. */
                     77: 
                     78:        if ((mdp = find(name, root, &dp)) != NULL) {
                     79:                if (!isdir(mdp))
                     80:                {
                     81:                        if (mdp->m_attr & MVOLUME)
                     82:                                fatal("\"%s\" is the volume name, not a subdirectory", name);
                     83:                        else
                     84:                                fatal("\"%s\" is an MS-DOS file, not a subdirectory", name);
                     85:                }
                     86: 
                     87:                return dp;
                     88:        }
                     89: 
                     90:        /* Directory does not exist, create it. */
                     91:        dbprintf(("creatdir(%s)\n", name));
                     92:        if ((cp = strrchr(name, '/')) == NULL) {
                     93:                dp = root;
                     94:                mdp = creatfile(name, dp);      /* create the dir in root */
                     95:        } else {
                     96:                *cp = '\0';                     /* NUL-terminate dirname */
                     97:                dp = creatdir(name);            /* create the parent */
                     98:                *cp = '/';                      /* restore the / */
                     99:                mdp = creatfile(cp + 1, dp);    /* create the directory */
                    100:        }
                    101:        if (vflag)
                    102:                fprintf(stderr, "r %s/\n", name);
                    103:        mdp->m_attr = MSUBDIR;
                    104:        ndp = newdir(dp, mdp, mdirsize);
                    105:        readmdir(ndp);
                    106:        mdp->m_cluster = ndp->d_cluster = freecluster();
                    107:        mdp = ndp->d_dir;
                    108:        mdirinit(mdp, ndp, ".          ", MSUBDIR, ndp->d_cluster);
                    109:        mdirinit(++mdp, ndp, "..         ", MSUBDIR, dp->d_cluster);
                    110:        return ndp;
                    111: }
                    112: 
                    113: /*
                    114:  * Create an empty MS-DOS file.
                    115:  * Delete the old one if it exists.
                    116:  * Return a pointer to the initialized MDIR entry
                    117:  * (name initialized, attribute==0, cluster==0, size==0L).
                    118:  * Failure is always fatal.
                    119:  */
                    120: MDIR *
                    121: creatfile(name, dp) char *name; DIR *dp;
                    122: {
                    123:        register MDIR *mdp;
                    124:        unsigned short n, ofiles, next;
                    125: 
                    126:        /* Check if file exists. */
                    127:        dbprintf(("creatfile(%s, %s)\n", name, dp->d_dname));
                    128:        if ((mdp = find(name, dp, &dp)) != NULL) {
                    129:                if isdir(mdp)
                    130:                        fatal("\"%s\" is an MS-DOS subdirectory", name);
                    131:                deletefile(mdp, dp);            /* delete the old one */
                    132:        }
                    133: 
                    134:        /* Find a slot for the file. */
                    135:        for (mdp = dp->d_dir; mdp < dp->d_edp; mdp++)
                    136:                if (mdp->m_name[0] == MEMPTY || mdp->m_name[0] == MFREE)
                    137:                        break;
                    138:        if (mdp == dp->d_edp) {
                    139:                /* Out of directory space.  Fatal on root. */
                    140:                if (dp == root)
                    141:                        fatal("replace: out of root directory space for \"%s\"", name);
                    142:                /* Add a cluster to a subdirectory. */
                    143:                for (n = dp->d_cluster; (next = getcluster(n)) <= CLMAX; n = next)
                    144:                        ;
                    145:                putcluster(n, freecluster());
                    146:                dp->d_dirblocks += clsize;
                    147:                ofiles = dp->d_files;
                    148:                dp->d_files += mdirsize;
                    149:                if ((dp->d_dir = (MDIR *)realloc(dp->d_dir, dp->d_dirblocks * ssize)) == NULL)
                    150:                        fatal("replace: out of space to grow subdirectory");
                    151:                dbprintf(("creatfile: grow \"%s\" dp=%x at d_dir=%x\n", dp->d_dname, dp, dp->d_dir));
                    152:                dp->d_edp = dp->d_dir + dp->d_files;
                    153:                for (mdp = dp->d_dir + ofiles + 1; mdp < dp->d_edp; mdp++)
                    154:                        mdp->m_name[0] = MFREE;
                    155:                mdp = dp->d_dir + ofiles;
                    156:        }
                    157:        mdirinit(mdp, dp, dosname(name), MARCHIV, 0);
                    158:        return mdp;
                    159: }
                    160: 
                    161: /*
                    162:  * Delete specified files.
                    163:  */
                    164: void
                    165: delete(nargs, args) short nargs; char *args[];
                    166: {
                    167:        register MDIR *mdp;
                    168:        register char **ap;
                    169:        DIR *dp;
                    170: 
                    171:        if (nargs == 0)
                    172:                fatal("delete: must specify files");
                    173:        for (ap = args; *ap != NULL; ap++) {
                    174:                if (vflag)
                    175:                        fprintf(stderr, "d %s\n", *ap);
                    176:                if ((mdp = find(*ap, root, &dp)) == NULL)
                    177:                        nonfatal("delete: \"%s\" not found", *ap);
                    178:                else {
                    179:                        do {
                    180:                                if isdir(mdp)
                    181:                                        deletedir(mdp, dp, cohn(mdp->m_name));
                    182:                                else
                    183:                                        deletefile(mdp, dp);
                    184:                        } while (mdp = findnext(&dp));
                    185:                }
                    186:        }
                    187: }
                    188: 
                    189: /*
                    190:  * Delete a subdirectory.
                    191:  * Make sure it is empty first.
                    192:  */
                    193: void
                    194: deletedir(mdp, dp, name) MDIR *mdp; DIR *dp; char *name;
                    195: {
                    196:        register MDIR *mdp2;
                    197:        register DIR **dpp;
                    198:        short c;
                    199: 
                    200:        /* Make sure subdirectory is empty. */
                    201:        for (mdp2 = dp->d_dir; mdp2 < dp->d_edp; mdp2++)
                    202:                if ((c = mdp2->m_name[0])!=MFREE && c!=MEMPTY && c!=MMDIR) {
                    203:                       nonfatal("delete: subdirectory \"%s\" not empty",name);
                    204:                       return;
                    205:                }
                    206: 
                    207:        /* Delete the subdirectory entry and free its MDIR. */
                    208:        deletefile(mdp, dp->d_parent);
                    209:        free(dp->d_dir);
                    210: 
                    211:        /* Remove the DIR from the chain and free it. */
                    212:        for (dpp = &(dp->d_parent->d_child); *dpp != NULL; dpp = &((*dpp)->d_sibling))
                    213:                if (*dpp == dp)
                    214:                        break;
                    215:        if (*dpp == NULL)
                    216:                fatal("deletedir botch");
                    217:        *dpp = dp->d_sibling;
                    218:        free(dp);
                    219: }
                    220: 
                    221: /*
                    222:  * Delete a file.
                    223:  * Free the clusters in its FAT chain.
                    224:  * Free the directory entry.
                    225:  * Set the dirflag requiring the directory to be updated.
                    226:  */
                    227: void
                    228: deletefile(mdp, dp) MDIR *mdp; DIR *dp;
                    229: {
                    230:        register unsigned short n, next;
                    231: 
                    232:        if ((mdp->m_attr & MRONLY) && !fflag)
                    233:        {
                    234:                nonfatal("cannot delete %s\n", cohn(mdp->m_name));
                    235:                return;
                    236:        }
                    237: 
                    238:        dp->d_dirflag = 1;
                    239:        mdp->m_name[0] = MEMPTY;                /* zap the MDIR entry */
                    240:        if (mdp->m_cluster == 0)
                    241:                return;                         /* no chain */
                    242:        for (n = mdp->m_cluster; n <= CLMAX; n = next) {
                    243:                next = getcluster(n);
                    244:                putcluster(n, CLFREE);
                    245:        }
                    246:        mdp->m_cluster = CLFREE;
                    247: }
                    248: 
                    249: /*
                    250:  * Return the size in clusters of the directory starting at n.
                    251:  */
                    252: unsigned short
                    253: dirclusters(mdp) MDIR *mdp;
                    254: {
                    255:        register unsigned short n, count;
                    256: 
                    257:        for (n = mdp->m_cluster, count = 1; (n = getcluster(n)) <= CLMAX; ++count)
                    258:                ;
                    259:        return count;
                    260: }
                    261: 
                    262: /*
                    263:  * Map a COHERENT filename to an 11-character MS-DOS name (plus NUL terminator)
                    264:  * in the static buffer and return a pointer to it.
                    265:  * There is no good way, thanks to different filename lengths and '.'.
                    266:  * Special hacks: ".profile" -> "_PROFILE", "a.b.c" -> "A_B.C".
                    267:  */
                    268: char *
                    269: dosname(name) register char *name;
                    270: {
                    271:        register char *s, *dotp;
                    272:        char c;
                    273:        static char buf[16];
                    274: 
                    275:        dotp = strrchr(name, '.');
                    276:        if (dotp == name)
                    277:                dotp = NULL;
                    278:        for (s = buf; name != dotp && (c = *name) != '\0'; name++)
                    279:                if (s < &buf[8])                /* copy name */
                    280:                        *s++ = (c == '.') ? '_' : c;
                    281:        while (s < &buf[8])
                    282:                *s++ = ' ';                     /* space-pad name */
                    283:        if (name++ == dotp)
                    284:                for ( ; *name != '\0'; name++)
                    285:                        if (s <= &buf[11])
                    286:                                *s++ = *name;   /* copy extension */
                    287:        while (s < &buf[11])
                    288:                *s++ = ' ';                     /* space-pad extension */
                    289:        *s = '\0';                              /* NUL terminate */
                    290:        uppercase(buf);                         /* map to UPPER */
                    291:        return buf;
                    292: }
                    293: 
                    294: /*
                    295:  * Set the time of an MS-DOS directory entry.
                    296:  * Use the mtime of file if kflag and file is not NULL,
                    297:  * otherwise use the current time.
                    298:  */
                    299: void
                    300: dostime(mdp, file) register MDIR *mdp; char *file;
                    301: {
                    302:        register struct tm *tmp;
                    303:        struct stat s;
                    304:        time_t t;
                    305: 
                    306:        if (kflag && file != NULL) {
                    307:                if (stat(file, &s) == -1)
                    308:                        fatal("cannot stat \"%s\"", file);
                    309:                t = s.st_mtime;
                    310:        } else
                    311:                t = time(NULL);
                    312:        tmp = localtime(&t);
                    313:        mdp->m_time =
                    314:           c_sec(tmp->tm_sec/2) | c_min(tmp->tm_min) | c_hour(tmp->tm_hour);
                    315:        mdp->m_date =
                    316:           c_day(tmp->tm_mday)|c_month(tmp->tm_mon+1)|c_year(tmp->tm_year-80);
                    317: }
                    318: 
                    319: /*
                    320:  * creat a directory on a dos disk
                    321:  */
                    322: void
                    323: createdir(nargs, args) short nargs; char *args[];
                    324: {
                    325:        creatdir(*args);
                    326: }
                    327: 
                    328: 
                    329: /*
                    330:  * Extract files from MS-DOS file system.
                    331:  */
                    332: void
                    333: extract(nargs, args) short nargs; char *args[];
                    334: {
                    335:        register MDIR *mdp;
                    336:        register char **ap;
                    337:        char *argsd[512], *argsf[512];
                    338:        short dnargs = 0, fnargs = 0;
                    339:        char *tmp;
                    340:        DIR *dp;
                    341: 
                    342:        if ((clbuf = malloc(clsize * ssize)) == NULL)
                    343:                fatal("cluster buffer allocation failed");
                    344:        if (pflag && nargs!=1)
                    345:                fatal("extract: exactly one file required with 'p' option");
                    346:        if (nargs == 0)
                    347:                extractdir(root);
                    348:        else {
                    349:                if ((mdp = find(args[0], root, &dp)) == NULL)
                    350:                        nonfatal("extract: file \"%s\" not found", *ap);
                    351:                else {
                    352:                        do {
                    353:                                cohname(mdp->m_name, dp);
                    354:                                if (isdir(mdp)) {
                    355:                                        if (!sflag) {
                    356:                                                argsd[dnargs] =
                    357:                                                    malloc(strlen(cohfile)+1);
                    358:                                                strcpy(argsd[dnargs++],
                    359:                                                                cohfile);
                    360:                                        }
                    361:                                }
                    362:                                else {
                    363:                                        argsf[fnargs] =
                    364:                                                malloc(strlen(cohfile) + 1);
                    365:                                        strcpy(argsf[fnargs++],cohfile);
                    366:                                }
                    367:                        } while (mdp = findnext(&dp));
                    368:                        numargs = fnargs + (sflag ? 0 : dnargs);
                    369:                        if (fnargs > 0) {
                    370:                                for (ap = argsf; fnargs ; ap++, fnargs--) {
                    371:                                        isdir_keep = 0;
                    372:                                        mdp = find(*ap, root, &dp);
                    373:                                        base = basehold;
                    374:                                        strcpy(base,*ap);
                    375:                                        extractfile(mdp, dp);
                    376:                                }
                    377:                        }
                    378:                        if ((!sflag) && (dnargs > 0)) {
                    379:                                for (ap = argsd; dnargs ; ap++, dnargs--) {
                    380:                                        isdir_keep = 1;
                    381:                                        mdp = find(*ap, root, &dp);
                    382:                                        base = basehold;
                    383:                                        strcpy(base,*ap);
                    384:                                        extractdir(dp);
                    385:                                }
                    386:                        }
                    387:                }
                    388:        }
                    389:        free(clbuf);
                    390: }
                    391: 
                    392: /*
                    393:  * Extract a directory.
                    394:  * Extract subdirectories recursively unless sflag.
                    395:  */
                    396: void
                    397: extractdir(dp) register DIR *dp;
                    398: {
                    399:        register MDIR *mdp;
                    400:        DIR *dp2;
                    401:        unsigned char c;
                    402:        struct stat s;
                    403:        short freeflag;
                    404: 
                    405:        freeflag = 0;
                    406:        if (!sflag) {
                    407:                if (dp->d_dir == NULL) {
                    408:                        readmdir(dp);           /* read the DOS directory */
                    409:                        freeflag = 1;           /* and set a flag */
                    410:                }
                    411:                if (dp != root) {
                    412:                        cohname(dp->d_dname, dp->d_parent);
                    413:                        if (stat(cohfile, &s) == -1) {
                    414:                                /* COHERENT directory not found, create it. */
                    415:                                if (vflag)
                    416:                                        fprintf(stderr, "x %s/\n", cohfile);
                    417:                                if (oldstyle)
                    418:                                        if (system(strcat(strcpy(cmd, "mkdir "), cohfile)) != 0)
                    419:                                                fatal("cannot create directory \"%s\"", cohfile);
                    420:                        } else if ((s.st_mode & S_IFDIR) == 0)
                    421:                                fatal("\"%s\" exists but is not a directory",
                    422:                                        cohfile);
                    423:                }
                    424:                for (dp2 = dp->d_child; dp2 != NULL; dp2 = dp2->d_sibling)
                    425:                        extractdir(dp2);        /* extract subdirectory */
                    426:        }
                    427:        for (mdp = dp->d_dir; mdp < dp->d_edp; mdp++)
                    428:                if ((c = mdp->m_name[0]) != MEMPTY && c != MFREE && c != MMDIR && !isdir(mdp))
                    429:                        extractfile(mdp, dp);
                    430:        if (freeflag) {
                    431:                free(dp->d_dir);
                    432:                dp->d_dir = dp->d_edp = NULL;
                    433:        }
                    434: }
                    435: 
                    436: /*
                    437:  * Extract a file.
                    438:  */
                    439: void
                    440: extractfile(mdp, dp) register MDIR *mdp; DIR *dp;
                    441: {
                    442:        register unsigned short cluster;
                    443:        short readsize, i;
                    444:        long size;
                    445:        FILE *ofp;
                    446:        char *tmp, tmp2[6], *mcohfile;
                    447: 
                    448:        if (mdp->m_attr & MVOLUME)
                    449:                return;
                    450: 
                    451:        tmp = &(mdp->m_name[8]);
                    452:        if (!oldstyle) {
                    453:                if (!bflag && (*tmp != ' ')) {
                    454:                        tmp2[0] = '.';
                    455:                        for (i=0; i< 3; i++) {
                    456:                                if (tmp[i] != ' ')
                    457:                                        tmp2[i+1] = tolower(tmp[i]);
                    458:                                else
                    459:                                        break;
                    460:                        }
                    461:                        tmp2[i+1] = '.';
                    462:                        tmp2[i+2] = '\0';
                    463:                        if (!aflag)
                    464:                                aflag = (strstr(ext, tmp2) != NULL) ? 1 : 0;
                    465:                }
                    466:        }
                    467: 
                    468: dbprintf(("bflag=%d, aflag=%d, mdp->m_name=%s, tmp2=%s\n", bflag, aflag, mdp->m_name, tmp2));
                    469: 
                    470:        /* Convert filename to COHERENT format and open the output file. */
                    471:        cohname(mdp->m_name, dp);
                    472: 
                    473:        if (pflag)
                    474:                        ofp = stdout;
                    475:        else if ((ofp = fopen(mcohfile = makef(cohfile, 1), "w")) == NULL)
                    476:                fatal("extract: cannot create file \"%s\"", mcohfile);
                    477: 
                    478:        if (vflag)
                    479:                fprintf(stderr, "x %s\n", mcohfile);
                    480: 
                    481:        /* Read the MS-DOS file and write it to the COHERENT file. */
                    482:        readsize = clsize * ssize;
                    483:        size = mdp->m_size;
                    484:        for(cluster= mdp->m_cluster; size > 0; cluster = getcluster(cluster)){
                    485:                if (cluster > CLMAX)
                    486:                        fatal("extract: early EOF on file \"%s\"",mcohfile);
                    487:                if (diskread(clbuf, cltosec(cluster), clsize))
                    488:                        fatal("extract: read error on file \"%s\"", mcohfile);
                    489:                if (size < readsize)
                    490:                        readsize = size;
                    491:                foutput(mcohfile, ofp, clbuf, readsize);
                    492:                size -= readsize;
                    493:        }
                    494:        if (!pflag)
                    495:                fclose(ofp);
                    496:        if (kflag)
                    497:                cohtime(mcohfile, mdp);
                    498: }
                    499: 
                    500: /* end of dos2.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.