Annotation of coherent/d/bin/dos/dosshrink.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * dosshrink.c
        !             3:  * 4/2/90
        !             4:  *
        !             5:  * Usage: dosshrink [ -cv ] xdevice part device
        !             6:  * Options:
        !             7:  *     -c      Check only, do not write changes
        !             8:  *     -v      Print verbose description of actions
        !             9:  * Default device is defined by INFILE in dos1.h.
        !            10:  *
        !            11:  * Restructure the given MSDOS filesystem
        !            12:  * by shifting files forward to first available free space.
        !            13:  *
        !            14:  * Uses functions defined in dos1.c:
        !            15:  *     cc -o dosshrink dosshrink.c dos1.c -f
        !            16:  * Produces extra debugging output if compiled with DEBUG or FATDUMP defined.
        !            17:  */
        !            18: 
        !            19: #include "dos1.h"
        !            20: #include <sys/fdisk.h>
        !            21: #include <sys/hdioctl.h>
        !            22: 
        !            23: #define        VERSION "1.3"                   /* Version id                   */
        !            24: #define        USAGE   "Usage:\t/etc/dosshrink [ -cv ] xdevice part device\n"
        !            25: #define        NBUF    128                     /* interactive input buffer size */
        !            26: #define offsetof(s,id) ((long)(&(((s *)0)->id)))
        !            27: 
        !            28: /* (unsigned int) clusters to (double) megabytes. */
        !            29: #define        meg(cl) (((double)(cl))*clsize*ssize/1000000.)
        !            30: 
        !            31: /* Consistency check cluster bitmap. */
        !            32: #define        CHAR_BIT        8               /* Bits per char                */
        !            33: #define        isflag(n)       ((bitmap[n/CHAR_BIT] >> (n%CHAR_BIT)) & 1)
        !            34: #define        setflag(n)      bitmap[n/CHAR_BIT] |= 1 << (n%CHAR_BIT);
        !            35: 
        !            36: /* Conversions. */
        !            37: #define        sec_to_c(sec)   ((unsigned)((sec) / (heads * nspt)))
        !            38: #define        sec_to_h(sec)   ((unsigned)(((sec) / nspt) % heads))
        !            39: #define        sec_to_s(sec)   ((unsigned)(((sec) % nspt) + 1))
        !            40: 
        !            41: /* Clear the IBM AT console screen. */
        !            42: #define        cls()   putchar(0x1B); putchar('c'); fflush(stdout)
        !            43: 
        !            44: /* Externals. */
        !            45: extern         double  atof();
        !            46: extern char    *calloc();
        !            47: extern char    *malloc();
        !            48: extern char    *memcpy();
        !            49: extern char    *memset();
        !            50: extern char    *realloc();
        !            51: 
        !            52: /* Functions. */
        !            53: extern void            checkdir();
        !            54: extern void            consistency();
        !            55: #if    DEBUG
        !            56: extern void            dumpname();
        !            57: #endif
        !            58: extern void            info();
        !            59: extern MDIR            *readdir();
        !            60: extern void            readpart();
        !            61: extern void            shuffle();
        !            62: extern unsigned int    shuffle1();
        !            63: extern MDIR            *writedir();
        !            64: extern void            writepart();
        !            65: 
        !            66: /* Globals. */
        !            67: unsigned char  *bitmap;                /* Consistency check bitmap     */
        !            68: unsigned int   maxhidden;              /* Max hidden cluster           */
        !            69: unsigned int   nclusters;              /* Clusters written             */
        !            70: unsigned int   ndirs;                  /* Directories written          */
        !            71: unsigned int   removed;                /* Number of clusters removed   */
        !            72: unsigned int   scluster;               /* First cluster to shuffle     */
        !            73: 
        !            74: int
        !            75: main(argc, argv) int argc; char *argv[];
        !            76: {
        !            77:        FDISK_S hd_part;
        !            78:        int xfd, partno;
        !            79:        register char c;
        !            80:        register char *s;
        !            81: 
        !            82:        argv0 = argv[0];
        !            83:        usagemsg = USAGE;
        !            84:        while (argc > 1 && argv[1][0] == '-') {
        !            85:                s = &argv[1][1];
        !            86:                --argc;
        !            87:                ++argv;
        !            88:                while ((c = *s++) != '\0') {
        !            89:                        if (c == 'c')
        !            90:                                ++cflag;
        !            91:                        else if (c == 'v')
        !            92:                                ++vflag;
        !            93:                        else if (c == 'V')
        !            94:                                fprintf(stderr, "%s: V%s\n", argv0, VERSION);
        !            95:                        else
        !            96:                                usage();
        !            97:                }
        !            98:        }
        !            99:        if (argc != 4)
        !           100:                usage();
        !           101:        if ((xfd = open(argv[1], (cflag) ? 0 : 2)) < 0)
        !           102:                fatal("cannot open partition table device \"%s\"", argv[1]);
        !           103:        if ((partno = atoi(argv[2])) < 0 || partno >= NPARTN)
        !           104:                fatal("invalid partition number %d\n", partno);
        !           105:        readpart(xfd, partno, &hd_part);
        !           106:        if ((fsfd = open(argv[3], (cflag) ? 0 : 2)) < 0)
        !           107:                fatal("cannot open file system \"%s\"", argv[3]);
        !           108:        info();
        !           109:        if (scluster != 0) {
        !           110:                if ((clbuf = malloc(clsize * ssize)) == NULL)
        !           111:                        fatal("cluster buffer allocation failed");
        !           112:                shuffle(0, 0);                  /* shuffle clusters */
        !           113:                free(clbuf);
        !           114:        }
        !           115:        writepart(xfd, partno, &hd_part);       /* write new partition info */
        !           116:        if (fatflag)
        !           117:                writefat();                     /* write new FAT */
        !           118:        if (vflag)
        !           119:                printf("%s %u directories and moved %u clusters\n",
        !           120:                        (cflag) ? "would have rewritten" : "rewrote",
        !           121:                        ndirs, nclusters);
        !           122:        if (close(fsfd) == -1)
        !           123:                fatal("cannot close file system \"%s\"", argv[3]);
        !           124:        exit(0);
        !           125: }
        !           126: 
        !           127: /*
        !           128:  * Read an MSDOS directory and mark used clusters.
        !           129:  * Read subdirectories recursively.
        !           130:  */
        !           131: void
        !           132: checkdir(cluster, parent) unsigned int cluster, parent;
        !           133: {
        !           134:        register MDIR *mdp, *mp;
        !           135:        MDIR *edp;
        !           136:        register unsigned int n;
        !           137:        int hflag;
        !           138: 
        !           139:        dbprintf(("checkdir(%u, %u)\n", cluster, parent));
        !           140: 
        !           141:        /* Scan through the directory. */
        !           142:        for (mdp = mp = readdir(cluster, &edp); mdp < edp; mdp++) {
        !           143:                if ((n = mdp->m_name[0]) == MFREE || n == MEMPTY)
        !           144:                        continue;               /* never used or erased */
        !           145:                else if (n == MMDIR) {          /* "." or "..", hopefully */
        !           146:                        if ((n = mdp->m_name[1]) == MMDIR && mdp->m_cluster == parent)
        !           147:                                continue;
        !           148:                        else if (n == ' ' && mdp->m_cluster == cluster)
        !           149:                                continue;
        !           150:                        else
        !           151:                                fatal("checkdir: \"%c%c\" %u %u %u",
        !           152:                                        MMDIR, n, mdp->m_cluster, cluster, parent);
        !           153:                } else if (mdp->m_size == 0L && !isdir(mdp))    /* 0-size file */
        !           154:                        continue;
        !           155: #if    DEBUG
        !           156:                dumpname(mdp);
        !           157: #endif
        !           158:                hflag = ishidden(mdp);
        !           159:                for (n = mdp->m_cluster; n <= CLMAX; n = getcluster(n)) {
        !           160:                        if (n < 2 || n > maxcluster)
        !           161:                                fatal("checkdir: bad cluster number %u", n);
        !           162:                        else if (isflag(n))
        !           163:                                fatal("cross-linked cluster %u", n);
        !           164:                        else
        !           165:                                setflag(n);
        !           166:                        if (hflag && n > maxhidden)
        !           167:                                maxhidden = n;
        !           168:                }
        !           169:                if (n <= CLBAD)
        !           170:                        fatal("unexpected 0x%x in file cluster chain", n);
        !           171:                if (isdir(mdp))
        !           172:                        checkdir(mdp->m_cluster, cluster);
        !           173:        }
        !           174:        free(mp);
        !           175: }
        !           176: 
        !           177: /*
        !           178:  * Consistency check.
        !           179:  */
        !           180: void
        !           181: consistency()
        !           182: {
        !           183:        register unsigned int i, n;
        !           184: 
        !           185:        if ((bitmap = calloc((maxcluster+1+CHAR_BIT-1)/CHAR_BIT, 1)) == NULL)
        !           186:                fatal("bitmap allocation failed");
        !           187:        checkdir(0, 0);                         /* recursive starting at root */
        !           188:        for (i = 2; i <= maxcluster; i++) {
        !           189:                if (isflag(i))
        !           190:                        continue;               /* marked used by checkdir */
        !           191:                n = fat[i];                     /* FAT value */
        !           192:                if (n == CLFREE || (n > CLMAX && n <= CLBAD))
        !           193:                        continue;               /* free, bad or reserved */
        !           194:                else
        !           195:                        fatal("lost cluster %u, value %u", i, n);
        !           196:        }
        !           197:        free(bitmap);
        !           198: }
        !           199: 
        !           200: #if    DEBUG
        !           201: /*
        !           202:  * Print an MS-DOS filename.
        !           203:  */
        !           204: void
        !           205: dumpname(mdp) register MDIR *mdp;
        !           206: {
        !           207:        register char *cp;
        !           208:        char buf[13];
        !           209: 
        !           210:        cp = lcname(buf, mdp->m_name, 8);
        !           211:        if (mdp->m_ext[0] != ' ') {
        !           212:                *cp++ = '.';
        !           213:                cp = lcname(cp, mdp->m_ext, 3);
        !           214:        }
        !           215:        printf("%s:\n", buf);
        !           216: }
        !           217: #endif
        !           218: 
        !           219: /*
        !           220:  * Print information about the MS-DOS file system.
        !           221:  */
        !           222: void
        !           223: info()
        !           224: {
        !           225:        static char buf[NBUF];
        !           226:        register unsigned int n, i;
        !           227:        unsigned int free, bad, reserved, eof, ordinary;
        !           228:        unsigned int used, dosused, dosfree, minfree, maxused;
        !           229: 
        !           230:        cls();
        !           231:        readfat();
        !           232:        if (vflag)
        !           233:                printf("heads=%u nspt=%u clsize=%u ssize=%u\n",
        !           234:                        heads, nspt, clsize, ssize);
        !           235:        free = bad = reserved = eof = ordinary = maxused = 0;
        !           236:        for (n = 2; n <= maxcluster; n++) {
        !           237: #if    FATDUMP
        !           238:                printf("fat[%u]=%u\n", n, getcluster(n));
        !           239: #endif
        !           240:                if ((i = getcluster(n)) == 0)
        !           241:                        ++free;
        !           242:                else if (i == CLBAD)
        !           243:                        ++bad;
        !           244:                else if (i > CLMAX && i < CLBAD)
        !           245:                        ++reserved;
        !           246:                else if (i == CLEOF) {
        !           247:                        ++eof;
        !           248:                        maxused = n;
        !           249:                } else {
        !           250:                        ++ordinary;
        !           251:                        maxused = n;
        !           252:                }
        !           253:        }
        !           254:        if (vflag) {
        !           255:                printf("%u clusters: %u free, %u EOF, %u continuation, %u bad, %u reserved\n",
        !           256:                        maxcluster - 1, free, eof, ordinary, bad, reserved);
        !           257:                printf("maxused=%u\n", maxused);
        !           258:        }
        !           259: 
        !           260:        /* Make sure the file system is consistent with the FAT. */
        !           261:        consistency();
        !           262:        if (vflag)
        !           263:                printf("maxhidden=%u\n", maxhidden);
        !           264: 
        !           265:        used = ordinary + eof;
        !           266:        printf("The MS-DOS file system currently contains:\n");
        !           267:        printf("\t%6.2f\tmegabytes used,\n", meg(used));
        !           268:        printf("\t%6.2f\tmegabytes free,\n", meg(free));
        !           269:        if (bad != 0)
        !           270:                printf("\t%6.2f\tmegabytes in bad clusters,\n", meg(bad));
        !           271:        if (reserved != 0)
        !           272:                printf("\t%6.2f\tmegabytes reserved,\n", meg(reserved));
        !           273:        printf("or\t%6.2f\tmegabytes total.\n", meg(maxcluster-1));
        !           274:        if (maxhidden > used) {
        !           275:                minfree = maxhidden - (used);
        !           276:                printf("This program will not move hidden files, which are sometimes\n");
        !           277:                printf("used by copy protection schemes.  Because of a hidden file,\n");
        !           278:                printf("you must leave at least %.2f megabytes free for MS-DOS.\n",
        !           279:                        meg(minfree));
        !           280:        } else
        !           281:                minfree = 0;
        !           282:        printf("\n");
        !           283: again:
        !           284:        printf("How many megabytes do you wish leave for use by MS-DOS? ");
        !           285:        fflush(stdout);
        !           286:        fgets(buf, NBUF, stdin);
        !           287:        dosused = (unsigned)(atof(buf) * 1000000. / (clsize * ssize));
        !           288:        dosfree = dosused - used;
        !           289:        if (dosused < used || dosfree < minfree || dosfree > free) {
        !           290:                printf("Please enter a value between %.2f and %.2f.\n",
        !           291:                        meg(used + minfree), meg(used + free));
        !           292:                goto again;
        !           293:        } else
        !           294:                free -= dosfree;
        !           295:        printf("The modified file system will contain %.2f free megabytes.\n",
        !           296:                meg(dosfree));
        !           297:        printf("The unused space after the file system will contain %.2f free megabytes.\n",
        !           298:                meg(free));
        !           299:        if (!cflag) {
        !           300:                printf("Do you want to modify the MS-DOS file system [y]?");
        !           301:                fgets(buf, NBUF, stdin);
        !           302:                if (buf[0] != '\0' && buf[0] != '\n' && buf[0] != 'y')
        !           303:                        fatal("aborted");
        !           304:        }
        !           305: 
        !           306:        /* Find the first cluster which needs to be shuffled. */
        !           307:        removed = scluster = 0;
        !           308:        for (n = maxcluster; free > 0 && n >= 2; n--) {
        !           309:                ++removed;
        !           310:                if ((i = getcluster(n)) == CLFREE)
        !           311:                        --free;
        !           312:                else if (i <= CLMAX || i == CLEOF) {
        !           313:                        --free;
        !           314:                        scluster = n;
        !           315:                }
        !           316:        }
        !           317:        if (vflag)
        !           318:                printf("removed=%u\nscluster=%u\n", removed, scluster);
        !           319: }
        !           320: 
        !           321: /*
        !           322:  * Read an MSDOS directory.
        !           323:  * Return a pointer to the allocated directory buffer.
        !           324:  * Store an end pointer through epp.
        !           325:  */
        !           326: MDIR *
        !           327: readdir(cluster, epp) unsigned int cluster; MDIR **epp;
        !           328: {
        !           329:        register MDIR *mdp, *mp, *edp;
        !           330:        register unsigned int n, c, blocks, files;
        !           331:        static unsigned int rootfiles;
        !           332: 
        !           333:        if (cluster == 0) {
        !           334:                if (rootfiles == 0) {
        !           335:                        files = bpb->b_files;
        !           336:                        blocks = dirsize;
        !           337:                } else {
        !           338:                        files = rootfiles;
        !           339:                        blocks = (files * sizeof(MDIR) + ssize - 1) / ssize;
        !           340:                }
        !           341:        } else {
        !           342:                for (c = cluster, blocks = 1; (c = getcluster(c)) <= CLMAX; ++blocks)
        !           343:                        ;
        !           344:                blocks *= clsize;
        !           345:                files = blocks * BSIZE / sizeof(MDIR);
        !           346:        }
        !           347:        dbprintf(("readdir(cluster=%u) files=%u blocks=%u\n", cluster, files, blocks));
        !           348:        if ((mp = (MDIR *)malloc(blocks * BSIZE)) == NULL)
        !           349:                fatal("directory allocation failed");
        !           350:        mdp = mp;
        !           351:        if (cluster == 0)
        !           352:                diskread(mdp, dirbase, blocks, "directory");
        !           353:        else
        !           354:                for (n = cluster; n <= CLMAX; n = getcluster(n)) {
        !           355:                        diskread(mdp, cltosec(n), clsize, "subdirectory");
        !           356:                        mdp += mdirsize;
        !           357:                }
        !           358: 
        !           359:        /* To conserve space, free unused portion of directory. */
        !           360:        for (mdp = mp; mdp < mp + files; mdp++)
        !           361:                if ((n = mdp->m_name[0]) != MFREE && n != MEMPTY)
        !           362:                        edp = mdp;
        !           363:        if (++edp != mp + files && realloc(mp, (char *)edp - (char *)mp) == NULL)
        !           364:                fatal("realloc failed");
        !           365:        if (cluster == 0)
        !           366:                rootfiles = edp - mp;
        !           367:        *epp = edp;
        !           368:        return mp;
        !           369: }
        !           370: 
        !           371: /*
        !           372:  * Read an entry from the partition table.
        !           373:  * Look for a valid signature.
        !           374:  */
        !           375: void
        !           376: readpart(xfd, partno, pp) int xfd, partno; FDISK_S *pp;
        !           377: {
        !           378:        unsigned short sig;
        !           379: 
        !           380:        if (lseek(xfd, offsetof(HDISK_S, hd_partn[partno]), 0) == -1)
        !           381:                fatal("partition table seek failed");
        !           382:        else if (read(xfd, pp, sizeof(FDISK_S)) != sizeof(FDISK_S))
        !           383:                fatal("partition table read failed");
        !           384:        else if (lseek(xfd, offsetof(HDISK_S, hd_sig), 0) == -1)
        !           385:                fatal("partition table seek failed");
        !           386:        else if (read(xfd, &sig, sizeof sig) != sizeof sig)
        !           387:                fatal("partition table read failed");
        !           388:        else if (sig != HDSIG)
        !           389:                fatal("invalid partition table signature %x", sig);
        !           390: }
        !           391: 
        !           392: /*
        !           393:  * Shuffle blocks, rewrite FAT and subdirectory entries
        !           394:  * to shift all files to front of file system.
        !           395:  * To keep life simple, this moves as few blocks as possible;
        !           396:  * each free block at the front is replaced by a used block from the back.
        !           397:  * Watch out for moving subdirectories (with "." and ".." entries)
        !           398:  * and for the readonly flag (where nothing really changes on the file system).
        !           399:  */
        !           400: void
        !           401: shuffle(cluster, parent) unsigned int cluster, parent;
        !           402: {
        !           403:        register MDIR *mdp, *mp, *edp;
        !           404:        register unsigned int n, lastn, changed;
        !           405: 
        !           406:        dbprintf(("shuffle(%u, %u)\n", cluster, parent));
        !           407:        /* Scan through the directory. */
        !           408:        changed = 0;
        !           409:        for (mdp = mp = readdir(cluster, &edp); mdp < edp; mdp++) {
        !           410:                if ((n = mdp->m_name[0]) == MFREE || n == MEMPTY)
        !           411:                        continue;               /* empty or never used */
        !           412:                else if (n == MMDIR) {          /* "." or ".." */
        !           413:                        /* Watch out for "." and "..", something may have moved. */
        !           414:                        if ((n = mdp->m_name[1]) == MMDIR) {
        !           415:                                if (mdp->m_cluster != parent) {
        !           416:                                        mdp->m_cluster = parent;
        !           417:                                        ++changed;
        !           418:                                }
        !           419:                        } else if (n == ' ') {
        !           420:                                if (mdp->m_cluster != cluster) {
        !           421:                                        mdp->m_cluster = cluster;
        !           422:                                        ++changed;
        !           423:                                }
        !           424:                        } else
        !           425:                                fatal("shuffle: \"%c%c\" botch", MMDIR, n);
        !           426:                        continue;
        !           427:                } else if (mdp->m_size == 0L && !isdir(mdp))    /* 0-size file */
        !           428:                        continue;
        !           429:                lastn = 0;
        !           430:                for (n = mdp->m_cluster; n <= CLMAX; n = getcluster(n)) {
        !           431:                        if (n < 2 || n > maxcluster)
        !           432:                                fatal("shuffle: bad cluster number %u", n);
        !           433:                        if (n >= scluster) {
        !           434:                                n = shuffle1(n);
        !           435:                                if (lastn == 0) {
        !           436:                                        mdp->m_cluster = n;
        !           437:                                        ++changed;
        !           438:                                } else
        !           439:                                        putcluster(lastn, n);
        !           440:                        }
        !           441:                        lastn = n;
        !           442:                }
        !           443:                if (isdir(mdp))
        !           444:                        shuffle(mdp->m_cluster, cluster);
        !           445:        }
        !           446:        if (changed) {
        !           447:                ++ndirs;
        !           448:                /* Rewrite the directory on the disk. */
        !           449:                dbprintf(("rewrite disk directory cluster=%u\n", cluster));
        !           450:                if (!cflag) {
        !           451:                        mdp = mp;
        !           452:                        if (cluster == 0)
        !           453:                                writedir(mdp, edp, dirbase, dirsize);
        !           454:                        else
        !           455:                                for (n = cluster; n <= CLMAX; n = getcluster(n))
        !           456:                                        mdp = writedir(mdp, edp, cltosec(n), clsize);
        !           457:                }
        !           458:        }
        !           459:        free(mp);
        !           460: }
        !           461: 
        !           462: /*
        !           463:  * Shuffle cluster n to the first free cluster.
        !           464:  * Return the new cluster number.
        !           465:  * The directory or FAT entry which points to n gets updated by the caller.
        !           466:  */
        !           467: unsigned int
        !           468: shuffle1(n) unsigned int n;
        !           469: {
        !           470:        register unsigned int i;
        !           471: 
        !           472:        ++nclusters;
        !           473:        for (i = 2; i <= maxcluster; i++)
        !           474:                if (getcluster(i) == CLFREE)
        !           475:                        break;
        !           476:        if (i > maxcluster)
        !           477:                fatal("no free blocks in shuffle1");
        !           478:        dbprintf(("cluster %u -> %u\n", n, i));
        !           479:        putcluster(i, getcluster(n));           /* next cl to new FAT entry */
        !           480:        if (cflag)
        !           481:                return n;                       /* return old value */
        !           482:        putcluster(n, CLFREE);                  /* free current FAT entry */
        !           483:        diskread(clbuf, cltosec(n), clsize, "cluster");
        !           484:        diskwrite(clbuf, cltosec(i), clsize, "cluster");        /* copy cluster */
        !           485:        return i;
        !           486: }
        !           487: 
        !           488: /*
        !           489:  * Rewrite a directory.
        !           490:  * The directory entries start at mdp and end at edp.
        !           491:  * The target is nsecs sectors starting at sector n.
        !           492:  * Pad with zeros if necessary.
        !           493:  * Return a pointer past the last byte written from mdp.
        !           494:  * Use the cluster buffer clbuf to write up to one cluster at a time.
        !           495:  * This is all necessary only because of the code which realloc's
        !           496:  * directories, to save space; otherwise, it would be a diskwrite() call.
        !           497:  */
        !           498: MDIR *
        !           499: writedir(mdp, edp, n, nsecs) register MDIR *mdp, *edp; unsigned int n, nsecs;
        !           500: {
        !           501:        unsigned int secs, nb, mb, s1, s2;
        !           502: 
        !           503:        diskseek(n);
        !           504:        while (nsecs != 0) {
        !           505:                mb = (char *)edp - (char *)mdp;         /* bytes at mdp */
        !           506:                secs = (nsecs <= clsize) ? nsecs : clsize;      /* sectors */
        !           507:                nb = secs * ssize;                      /* bytes in clbuf */
        !           508:                s1 = (mb <= nb) ? mb : nb;              /* mdp bytes */
        !           509:                s2 = nb - s1;                           /* zero bytes */
        !           510:                if (s1 != 0)
        !           511:                        memcpy(clbuf, mdp, s1);
        !           512:                if (s2 != 0)
        !           513:                        memset(clbuf + s1, 0, s2);
        !           514:                if (write(fsfd, clbuf, nb) != nb)
        !           515:                        fatal("directory write error");
        !           516:                nsecs -= secs;
        !           517:                mdp += s1;
        !           518:        }
        !           519:        return mdp;
        !           520: }
        !           521: 
        !           522: /*
        !           523:  * Write an updated partition table entry.
        !           524:  * Also update the sector count in the BPB.
        !           525:  */
        !           526: void
        !           527: writepart(xfd, partno, pp) int xfd, partno; FDISK_S *pp;
        !           528: {
        !           529:        unsigned int c, h, s;
        !           530:        unsigned long size, end;
        !           531:        int ofatbytes;
        !           532: 
        !           533:        if (cflag)
        !           534:                return;
        !           535: 
        !           536:        size = pp->p_size;                      /* old size */
        !           537:        size -= clsize * (long) removed;        /* new size */
        !           538:        end = pp->p_base + size - 1;            /* new end */
        !           539:        c = sec_to_c(end);
        !           540:        h = sec_to_h(end);
        !           541:        s = sec_to_s(end);
        !           542: 
        !           543:        /* Extend paritition to nearest track boundary. */
        !           544:        if (s != nspt) {
        !           545:                size += nspt - s;
        !           546:                end += nspt - s;
        !           547:                s = nspt;
        !           548:        }
        !           549: 
        !           550:        /* Update the size and end parameters in the partition table. */
        !           551:        pp->p_size = size;
        !           552:        pp->p_ecyl = c & 0xFF;
        !           553:        pp->p_ehd = h;
        !           554:        pp->p_esec = ((c >> 2) & CYLMASK) | s;
        !           555: 
        !           556:        /* Write the updated partition table entry. */
        !           557:        if (lseek(xfd, offsetof(HDISK_S, hd_partn[partno]), 0) == -1)
        !           558:                fatal("partition table seek failed");
        !           559:        else if (write(xfd, pp, sizeof(FDISK_S)) != sizeof(FDISK_S))
        !           560:                fatal("partition table read failed");
        !           561: 
        !           562:        /* Update the BPB sector count. */
        !           563:        if (lseek(fsfd, (long)BPBOFF + offsetof(BPB, b_sectors), 0) == -1)
        !           564:                fatal("BPB seek failed");
        !           565:        s = size;
        !           566:        if (write(fsfd, &s, sizeof s) != sizeof s)
        !           567:                fatal("BPB write failed");      
        !           568: 
        !           569:        /*
        !           570:         * If the partition shrinks enough,
        !           571:         * 2-byte FAT entries become 1.5-byte entries.
        !           572:         */
        !           573:        ofatbytes = fatbytes;
        !           574:        fatbytes = (size / clsize > (FATMASK & CLMAX)) ? 2 : 1;
        !           575:        if (ofatbytes != fatbytes)
        !           576:                ++fatflag;              /* rewrite the FAT */
        !           577: }
        !           578: 
        !           579: /* end of dosshrink.c */

unix.superglobalmegacorp.com

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