Annotation of coherent/d/bin/dos/dos2.c, revision 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.