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

1.1       root        1: /* #define DEBUG 1*/
                      2: /* dos4.c */
                      3: 
                      4: #include "dos0.h"
                      5: char *fequiv();
                      6: /*
                      7:  * Compare two MDIR names.
                      8:  * Directories precede ordinary files.
                      9:  * Called by qsort().
                     10:  */
                     11: short
                     12: namecmp(mdpp1, mdpp2) MDIR **mdpp1, **mdpp2;
                     13: {
                     14:        register MDIR *mdp1, *mdp2;
                     15:        unsigned long t1, t2;
                     16: 
                     17:        mdp1 = *mdpp1;
                     18:        mdp2 = *mdpp2;
                     19:        if (isdir(mdp1) != isdir(mdp2))
                     20:                return (isdir(mdp1)) ? -1 : 1;
                     21:        if (nflag) {
                     22:                /*
                     23:                 * Compare by time with unsigned long compare.
                     24:                 * m_junk[10] is really the first byte of the time.
                     25:                 * Kludgy but it works.
                     26:                 */
                     27:                t1 = *(unsigned long *)&mdp1->m_junk[10];
                     28:                t2 = *(unsigned long *)&mdp2->m_junk[10];
                     29:                if (t1 != t2)
                     30:                        return (t1 < t2) ? -1 : 1;
                     31:        }
                     32:        return strncmp(mdp1->m_name, mdp2->m_name, 11);
                     33: }
                     34: 
                     35: /*
                     36:  * Allocate a new DIR and link it into the DIR tree.
                     37:  * Initialize it with the supplied information.
                     38:  * Return a pointer to it.
                     39:  * The MDIR array is not allocated and read until required.
                     40:  */
                     41: DIR *
                     42: newdir(parent, mdp, files)
                     43: DIR *parent;
                     44: register MDIR *mdp;
                     45: short files;
                     46: {
                     47:        register DIR *dp;
                     48: 
                     49:        /* Allocate a new DIR. */
                     50:        dbprintf(("newdir(parent=\"%s\" mdp=%x files=%u): \n", (parent==NULL)?"<root>   ":parent->d_dname, mdp, files));
                     51:        if ((dp = (DIR *)malloc(sizeof(DIR))) == NULL)
                     52:                fatal("directory allocation failed");
                     53: 
                     54:        /* Initialize the DIR. */
                     55:        dp->d_parent = parent;
                     56:        dp->d_child = NULL;
                     57:        if (parent == NULL) {
                     58:                /* Root. */
                     59:                dp->d_sibling = NULL;
                     60:                dp->d_cluster = 0;
                     61:                strcpy(dp->d_dname, "<root>     ");
                     62:        } else {
                     63:                /* Subdirectory. */
                     64:                dp->d_sibling = parent->d_child;
                     65:                parent->d_child = dp;
                     66:                dp->d_cluster = mdp->m_cluster;
                     67:                strncpy(dp->d_dname, mdp->m_name, 11);
                     68:                dp->d_dname[11] = '\0';
                     69:        }
                     70:        dp->d_files = files;
                     71:        dp->d_dirblocks = (files * sizeof(MDIR) + ssize - 1) / ssize;
                     72:        dp->d_dir = dp->d_edp = NULL;
                     73:        dp->d_dirflag = 0;
                     74:        dbprintf(("\"%s\" cl=%x blocks=%u dp=%x\n", dp->d_dname, dp->d_cluster, dp->d_dirblocks, dp));
                     75:        return dp;
                     76: }
                     77: 
                     78: /*
                     79:  * Print a nonfatal error message.
                     80:  * Set the return status to 1.
                     81:  * Uses the nonportable "%r" format.
                     82:  */
                     83: void
                     84: nonfatal(x) char *x;
                     85: {
                     86:        fprintf(stderr, "dos: %r\n", &x);
                     87:        estat = 1;
                     88: }
                     89: 
                     90: /*
                     91:  * Allocate space for an MS-DOS directory.
                     92:  * Read in the directory unless dp is not root and its d_cluster is 0.
                     93:  */
                     94: void
                     95: readmdir(dp) register DIR *dp;
                     96: {
                     97:        register MDIR *mdp;
                     98:        register unsigned short n;
                     99: 
                    100:        dbprintf(("readmdir(%s) blocks=%u cl=%x\n", dp->d_dname, dp->d_dirblocks, dp->d_cluster));
                    101:        if ((mdp = (MDIR *)calloc(dp->d_dirblocks, ssize)) == NULL)
                    102:                fatal("directory allocation failed");
                    103:        dp->d_dir = mdp;
                    104:        dp->d_edp = mdp + dp->d_files;
                    105: 
                    106:        if (dp->d_cluster == 0) {
                    107:                if (dp->d_parent != NULL)
                    108:                        return;                 /* new subdirectory */
                    109:                diskread(mdp, (long)dirbase, dp->d_dirblocks, "directory");
                    110:        } else
                    111:                for (n = dp->d_cluster ; n <= CLMAX; n = getcluster(n)) {
                    112:                        diskread(mdp, cltosec(n), clsize, "subdirectory");
                    113:                        mdp += mdirsize;
                    114:                }
                    115: 
                    116:        /* Scan through the directory for volume label and subdirectories. */
                    117:        for (mdp = dp->d_dir; mdp < dp->d_edp; mdp++) {
                    118:                if ((n = mdp->m_name[0]) == MFREE || n == MEMPTY || n == MMDIR)
                    119:                        continue;
                    120:                if (mdp->m_attr & MVOLUME)
                    121:                        volume = mdp;
                    122:                if isdir(mdp)
                    123:                        newdir(dp, mdp, dirclusters(mdp) * mdirsize);
                    124:        }
                    125: }
                    126: 
                    127: /*
                    128:  * Replace one or more files on the MS-DOS file system.
                    129:  */
                    130: void
                    131: replace(nargs, args) short nargs; char *args[];
                    132: {
                    133:        register char **ap;
                    134:        struct stat s;
                    135: 
                    136:        if ((clbuf = malloc(clsize * ssize)) == NULL)
                    137:                fatal("cluster buffer allocation failed");
                    138:        if (nargs == 0)
                    139:                replacedir(NULL);
                    140:        else if (!strcmp(args[0], "-") || pflag) {
                    141:                pflag = 1;
                    142:                if (nargs!=1)
                    143:                        fatal("replace: exactly one file required with 'p' option");
                    144:                replacefile(args[0]);
                    145:        } else for (ap=args; nargs; ap++, nargs--) {
                    146:                if (stat(*ap, &s) == -1)
                    147:                        fatal("replace: \"%s\" not found", *ap);
                    148: 
                    149:                if (strncmp(*ap, "./", 2) == 0)
                    150:                        *ap += 2;
                    151: 
                    152:                if (strcmp(*ap, ".") == 0)
                    153:                {
                    154:                        replacedir(NULL);
                    155:                        break;
                    156:                }
                    157: 
                    158:                base = basehold;
                    159:                strcpy(base,*ap);
                    160: 
                    161:                if (s.st_mode & S_IFDIR) {
                    162:                        if (!sflag)
                    163:                                replacedir(*ap);
                    164:                }
                    165:                else
                    166:                        replacefile(*ap);
                    167:        }
                    168:        free(clbuf);
                    169: }
                    170: 
                    171: /*
                    172:  * Replace a directory; NULL means ".".
                    173:  * Replace subdirectories recursively unless sflag.
                    174:  */
                    175: void
                    176: replacedir(name) char *name;
                    177: {
                    178:        register struct direct *dirp;
                    179:        register char *cp;
                    180:        short fd;
                    181:        struct stat s;
                    182:        char dirbuf[sizeof(struct direct) + 1];
                    183:        char namebuf[NAMEMAX];
                    184: 
                    185:        dbprintf(("replacedir(%s)\n", name));
                    186:        if (name == NULL || strcmp(name, ".") == 0) {
                    187:                name = ".";
                    188:                cp = namebuf;
                    189:        } else {
                    190:                strcpy(namebuf, name);
                    191:                strcat(namebuf, "/");
                    192:                cp = &namebuf[strlen(namebuf)];
                    193:        }
                    194:        dirp = dirbuf;
                    195:        dirbuf[sizeof(struct direct)] = '\0';   /* NUL-terminate d_name */
                    196:        if ((fd = open(name, 0)) == -1)
                    197:                fatal("cannot search directory \"%s\"", name);
                    198:        while(read(fd,dirbuf, sizeof(struct direct))==sizeof(struct direct)) {
                    199:                if (dirp->d_ino == 0
                    200:                 || strcmp(dirp->d_name, ".") == 0
                    201:                 || strcmp(dirp->d_name, "..") == 0)
                    202:                        continue;
                    203:                strncpy(cp, dirp->d_name, DIRSIZ);
                    204:                cp[strlen(dirp->d_name)] = '\0';
                    205: 
                    206:                if (stat(namebuf, &s) == -1)
                    207:                        fatal("replacedir botch");
                    208:                else if (s.st_mode & S_IFDIR) {
                    209:                        if (!sflag)
                    210:                                replacedir(namebuf);
                    211:                }
                    212:                else if (s.st_mode & S_IFREG)
                    213:                        replacefile(namebuf);
                    214:        }
                    215:        close(fd);
                    216: }
                    217: 
                    218: /*
                    219:  * Replace a file.
                    220:  */
                    221: void
                    222: replacefile(file) char *file;
                    223: {
                    224:        register MDIR *mdp;
                    225:        register short nread;
                    226:        DIR *dp;
                    227:        FILE *ifp;
                    228:        char *cp, *filename;
                    229:        short writesize;
                    230:        unsigned short next, prev;
                    231:        char *tmp, tmp2[6], *files;
                    232: 
                    233:        if (!pflag && !oldstyle) {
                    234:                if (!bflag && ((tmp = strrchr(file, '.')) != NULL)) {
                    235:                        sprintf(tmp2, "%s.", tmp);
                    236:                        if (!aflag)
                    237:                                aflag = (strstr(ext, tmp2) != NULL) ? 1 : 0;
                    238:                }
                    239:        }
                    240: 
                    241:        /* Create the file in the appropriate directory. */
                    242:        dbprintf(("replacefile(%s)\n", file));
                    243:        files = makef(file, 0);
                    244: 
                    245:        if ((cp = strrchr(files, '/')) == NULL) {
                    246:                filename = files;
                    247:                dp = root;
                    248:        } else {
                    249:                filename = cp + 1;
                    250:                *cp = '\0';                     /* NUL-terminate dirname */
                    251:                dp = creatdir(files);           /* find the directory */
                    252:                *cp = '/';                      /* restore the / */
                    253:        }
                    254: 
                    255:        mdp = creatfile(filename, dp);          /* create the file */
                    256: 
                    257:        /* Read from the COHERENT file and write the MS-DOS file. */
                    258:        if (vflag)
                    259:                fprintf(stderr, "r %s\n", file);
                    260:        if (pflag)
                    261:                ifp = stdin;
                    262:        else if ((ifp = fopen(file, "r")) == NULL)
                    263:                fatal("replace: cannot open \"%s\"", file);
                    264:        writesize = clsize * ssize;
                    265:        for (prev = 0; ; prev = next) {
                    266:                if ((nread = finput(ifp, clbuf, writesize)) == 0)
                    267:                        break;
                    268:                mdp->m_size += nread;
                    269:                next = freecluster();
                    270:                if (prev == 0)
                    271:                        mdp->m_cluster = next;
                    272:                else
                    273:                        putcluster(prev, next);
                    274:                diskwrite(clbuf, cltosec(next), clsize, file);
                    275:                if (nread < writesize)
                    276:                        break;
                    277:        }
                    278:        if (nread < 0)
                    279:                fatal("replace: read error on file \"%s\"", file);
                    280:        if (!pflag)
                    281:                fclose(ifp);
                    282:        dostime(mdp, file);
                    283: }
                    284: 
                    285: #define NUM_D_RES      13
                    286: 
                    287: int istrcmp();
                    288: 
                    289: char * d_reserved[NUM_D_RES] =
                    290: {
                    291:     "aux",
                    292:     "clock$",
                    293:     "con",
                    294:     "com1",
                    295:     "com2",
                    296:     "com3",
                    297:     "com4",
                    298:     "lpt1",
                    299:     "lpt2",
                    300:     "lpt3",
                    301:     "lpt4",
                    302:     "nul",
                    303:     "prn"
                    304: };
                    305: 
                    306: /*
                    307:  * Make a full path from base and name
                    308:  */
                    309: char * makef(name, cr) char * name; short cr;
                    310: {
                    311:        static char tname[80];
                    312:        register char  *t = tname, *h;
                    313:        struct stat s;
                    314:        short done = 0, rs;
                    315:        register MDIR *mdp;
                    316:        short srcd, destd, deste;
                    317: 
                    318:        if (base1) {
                    319:                strcpy(t, base1);
                    320:                t += strlen(base1);
                    321: 
                    322:                if (cr) {
                    323:                        srcd = isdir_keep;
                    324:                        rs = stat(base1, &s);
                    325:                        deste = (rs == 0);
                    326:                        destd = (s.st_mode & S_IFDIR);
                    327:                }
                    328:                else {
                    329:                        mdp = find(base1,root,NULL);
                    330:                        deste = (mdp != NULL);
                    331:                        destd = isdir(mdp);
                    332:                        if (!pflag)
                    333:                        {
                    334:                                stat(base, &s);
                    335:                                srcd = (s.st_mode & S_IFDIR);
                    336:                        }
                    337:                        else
                    338:                                srcd = 0;
                    339:                }
                    340: 
                    341: /* dbprintf(("numargs = %d, deste = %d, destd = %d, srcd = %d\n",numargs,deste,destd,srcd));*/
                    342: 
                    343:                if (pflag)
                    344:                        if (destd)
                    345:                                fatal("Error: <%s> is a directory", base1);
                    346:                        else
                    347:                                done = 1;
                    348: 
                    349:                if ((numargs > 1) && (deste) && !(destd))
                    350:                        fatal("Error: <%s> is a file", base1);
                    351:                
                    352:                if (numargs == 1) {
                    353:                        if (!deste) {
                    354:                                if (!srcd)
                    355:                                        done = 1;
                    356:                        }
                    357:                        else {
                    358:                                if (!destd) {
                    359:                                        if (srcd)
                    360:                                                fatal("Error: <%s> is a file"
                    361:                                                                , base1);
                    362:                                        else
                    363:                                                done = 1;
                    364:                                }
                    365:                        }
                    366:                }
                    367:        }
                    368: 
                    369:        if (!done) {
                    370:                if ((h = fequiv(name)) != NULL) {
                    371:                        if (base1)
                    372:                                *t++ = '/';
                    373:                        strcpy(t, h);
                    374:                }
                    375:        }
                    376: 
                    377:        if (cr)
                    378:                maketree(tname);
                    379: 
                    380:         if ((t = strrchr(tname, '/')) != NULL)
                    381:            t++;
                    382:        else
                    383:            t = tname;
                    384: 
                    385:        if (bsearch(t, d_reserved, NUM_D_RES, sizeof (char *), istrcmp) != NULL)
                    386:        {
                    387:            printf("Dos reserved name used <%s>. Changing filename to <%s!>\n",
                    388:                        t, t);
                    389:             rs = strlen(t);
                    390:            t[rs] = '!';
                    391:            t[rs+1] = '\0';
                    392:        }
                    393: 
                    394: 
                    395: dbprintf(("base = <%s>, base1 = <%s>\n  name = <%s>, tname = <%s>\n", base, base1, name, tname));
                    396:        return tname;
                    397: }
                    398: 
                    399: istrcmp(a, b)
                    400: char *a, **b;
                    401: {
                    402:     return strcmp(a,*b);
                    403: }
                    404: 
                    405: char *fequiv(name) char *name;
                    406: {
                    407:        char *tmp;
                    408:        short basesize;
                    409: 
                    410:        if (!base)              /* No base at all means a full disk copy */
                    411:                return name;
                    412:                                /* No path means return the whole name */
                    413:        if (strchr(name, '/') == NULL)
                    414:                return name;
                    415: 
                    416:        if (!strcmp(base, name))  /* No wc or subdir means return the fname */
                    417:                return strrchr(name, '/') + 1;
                    418: 
                    419:        tmp = strrchr(base + 1, '/');
                    420: 
                    421:        if (tmp != NULL)
                    422:                basesize = tmp-base;
                    423:        else
                    424:                basesize = strlen(base);
                    425: 
                    426:        return name + basesize + 1;
                    427: }
                    428: 
                    429: maketree(name) char *name;
                    430: {
                    431: 
                    432:        char *h, c[80];
                    433:        struct stat s;
                    434: 
                    435:        h = strchr(name, '/');
                    436:        while (h) {
                    437:                *h = '\0';
                    438:                if (stat(name, &s) == -1) {
                    439:                        sprintf(c, "mkdir %s", name);   
                    440:                        system(c);
                    441:                        if (stat(name, &s) == -1)
                    442:                                fatal("Cannot create directory %s", name);
                    443:                        }
                    444:                *h = '/';
                    445:                h = strchr(h+1, '/');           
                    446:        }
                    447: }
                    448:                                
                    449: 
                    450: 
                    451: 
                    452: 
                    453: 
                    454: /*
                    455:  * Produce a listing of the MS-DOS file system.
                    456:  */
                    457: void
                    458: table(nargs, args) short nargs; char *args[];
                    459: {
                    460:        register unsigned short n, i;
                    461:        register char **ap, *npap, *temp;
                    462:        register MDIR *mdp;
                    463:        DIR *dp;
                    464:        short free, bad, reserved;
                    465:        char buf[12];
                    466: 
                    467:        if (vflag) {
                    468:                /* Print media information. */
                    469:                free = bad = reserved = 0;
                    470:                for (n = 2; n <= maxcluster; n++)
                    471:                        if ((i = getcluster(n)) == 0)
                    472:                                ++free;
                    473:                        else if (i == CLBAD)
                    474:                                ++bad;
                    475:                        else if (i > CLMAX && i < CLBAD)
                    476:                                ++reserved;
                    477:                if (volume == NULL)
                    478:                        printf("Unlabelled disk:\n");
                    479:                else {
                    480:                        strncpy(buf, volume->m_name, 11);
                    481:                        buf[11] = '\0';
                    482:                        printf("Volume in Drive %s is labeled %s\n",adev,buf);
                    483:                }
                    484:                printf("\t%lu bytes free\n",
                    485:                        (long unsigned)free*clsize*ssize);
                    486:                if (bad)
                    487:                        printf("\t%ld bytes in bad sectors\n",
                    488:                                (long)bad*clsize*ssize);
                    489:                if (reserved)
                    490:                        printf("\t%ld bytes in reserved sectors\n",
                    491:                                (long)reserved*clsize*ssize);
                    492:                putchar('\n');
                    493:        }
                    494:        if (nargs == 0)
                    495:                tabledir(root, NULL);
                    496:        else for (ap = args; *ap != NULL; ap++) {
                    497:                if ((mdp = find(*ap, root, &dp)) == NULL)
                    498:                        nonfatal("%s not found", *ap);
                    499:                else {
                    500:                        npap = (temp = strrchr(*ap, '/')) ? temp+1 : *ap;
                    501:                        do {
                    502:                                if((strcmp(npap,cohn(mdp->m_name)) == 0)
                    503:                                                            && isdir(mdp))
                    504: 
                    505:                                        tabledir(dp, cohn(mdp->m_name));
                    506:                                else
                    507:                                        tablefile(mdp, cohn(mdp->m_name));
                    508:                        } while (mdp = findnext(&dp));
                    509:                }
                    510:        }
                    511: }
                    512: 
                    513: /*
                    514:  * Print a sorted directory.
                    515:  * Suppress '.', '..' and volume label.
                    516:  */
                    517: void
                    518: tabledir(dp, name) register DIR *dp; char *name;
                    519: {
                    520:        register MDIR *mdp;
                    521:        register MDIR **pp, **beg, **end;
                    522:        unsigned char c;
                    523: 
                    524:        if (name != NULL)
                    525:                printf("Directory %s:\n", name);
                    526:        if ((beg = pp = (MDIR **)malloc(dp->d_files * sizeof(MDIR *))) == NULL)
                    527:                fatal("cannot allocate directory pointer table");
                    528:        for (mdp = dp->d_dir; mdp < dp->d_edp; mdp++)
                    529:                if ((c = mdp->m_name[0]) != MFREE && c != MEMPTY && c != MMDIR
                    530:                 && (mdp->m_attr & MVOLUME) == 0)
                    531:                        *pp++ = mdp;
                    532:        end = pp;
                    533:        qsort(beg, end - beg, sizeof(MDIR *), namecmp);
                    534:        for (pp = beg; pp < end; pp++)
                    535:                tablefile(*pp, NULL);
                    536:        free(beg);
                    537:        putchar('\n');
                    538: }
                    539: 
                    540: /*
                    541:  * Print a line describing a file.
                    542:  */
                    543: void
                    544: tablefile(mdp, name) register MDIR *mdp; char *name;
                    545: {
                    546:        register short attr;
                    547: 
                    548:        if (vflag) {
                    549:                attr = mdp->m_attr;
                    550:                putchar((attr & MRONLY ) ? 'r' : '-');
                    551:                putchar((attr & MHIDDEN) ? 'h' : '-');
                    552:                putchar((attr & MSYSTEM) ? 's' : '-');
                    553:                putchar((attr & MVOLUME) ? 'v' : '-');
                    554:                putchar((attr & MARCHIV) ? 'a' : '-');
                    555:                putchar((attr & MSUBDIR) ? 'd' : '-');
                    556: 
                    557:                printf("  %02d/%02d/%02d %02d:%02d %9ld  ",
                    558:                        m_month(mdp), m_day(mdp), m_year(mdp)+80,
                    559:                        m_hour(mdp),  m_min(mdp), (isdir(mdp)) ?
                    560:                           (long)dirclusters(mdp)*clsize*ssize : mdp->m_size);
                    561:        }
                    562: 
                    563:        if (name == NULL) {
                    564:                cohname(mdp->m_name, root);
                    565:                name = cohfile;
                    566:        }
                    567:        printf("%s\n", name);
                    568: }
                    569: 
                    570: 
                    571: /*
                    572:  * Convert NUL-terminated name to UPPERCASE in place.
                    573:  */
                    574: char *
                    575: uppercase(name) unsigned char *name;
                    576: {
                    577:        register unsigned char *s;
                    578:        register short c;
                    579: 
                    580:        for (s = name; (c = *s) != '\0'; s++)
                    581:                if (islower(c))
                    582:                        *s = toupper(c);
                    583:        return name;
                    584: }
                    585: 
                    586: /*
                    587:  * Write the changed directories of the MS-DOS file system.
                    588:  */
                    589: void
                    590: writedir(dp) register DIR *dp;
                    591: {
                    592:        register MDIR *mdp;
                    593:        register unsigned short n;
                    594: 
                    595:        if (dp->d_child != NULL)
                    596:                writedir(dp->d_child);
                    597:        if (dp->d_sibling != NULL)
                    598:                writedir(dp->d_sibling);
                    599:        mdp = dp->d_dir;
                    600:        dbprintf(("writedir(%s) flag=%u cl=%x blocks=%u mdp=%x\n",
                    601:              dp->d_dname, dp->d_dirflag, dp->d_cluster, dp->d_dirblocks, mdp));
                    602: 
                    603:        if (dp->d_dirflag == 0)
                    604:                return;                         /* DIR was unchanged */
                    605:        if (dp->d_cluster == 0)                 /* Write the root */
                    606:                diskwrite(dp->d_dir, (long)dirbase, dp->d_dirblocks, "directory");
                    607:        else                                    /* Write a subdirectory */
                    608:                for (mdp = dp->d_dir, n = dp->d_cluster; n <= CLMAX; n = getcluster(n)) {
                    609:                        diskwrite(mdp, cltosec(n), clsize, "subdirectory");
                    610:                        mdp += mdirsize;
                    611:                }
                    612: }
                    613: 
                    614: /* end of dos4.c */

unix.superglobalmegacorp.com

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