Annotation of researchv10no/cmd/savecore.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include <libc.h>
        !             3: #include <errno.h>
        !             4: #include <fstab.h>     /* only for compatibility hack/guess */
        !             5: 
        !             6: /*
        !             7:  * dump header.  manifest in the system;
        !             8:  * address and magic number are guaranteed not to change
        !             9:  */
        !            10: 
        !            11: #define        MAGICADDR 0x20          /* where the header always will be */
        !            12: #define        DUMPMAG 0x79646e61      /* magic number */
        !            13: #define        DUMPBAD 0               /* not the magic number */
        !            14: #define        DUMPBLK 512             /* dump size in these units */
        !            15: struct dumpmagic {
        !            16:        long magic;
        !            17:        long time;              /* when the dump was written */
        !            18:        long len;               /* 512-byte blocks in dump */
        !            19: };
        !            20: 
        !            21: struct dumpmagic *magic;
        !            22: struct dumpmagic *dumpdata();
        !            23: char *outfile, *infile;                /* only so we can print them */
        !            24: 
        !            25: #define        NBLKS   16              /* blocks of dump to read at once */
        !            26: 
        !            27: main(argc, argv)
        !            28: int argc;
        !            29: char **argv;
        !            30: {
        !            31:        char *writedir;
        !            32:        char *readname;
        !            33:        int fr, to;
        !            34: 
        !            35:        if (argc < 2) {
        !            36:                fprintf(stderr, "usage: savecore target dump\n");
        !            37:                exit(1);
        !            38:        }
        !            39:        setbuf(stdout, NULL);
        !            40:        writedir = argv[1];
        !            41:        readname = NULL;
        !            42:        if (argc > 2)
        !            43:                readname = argv[2];
        !            44:        if ((fr = opendump(readname)) < 0)
        !            45:                exit(2);                /* nothing to copy */
        !            46:        if ((to = openout(writedir)) < 0)
        !            47:                exit(1);
        !            48:        printf("%s %s: %ld bytes of crash dump from %s",
        !            49:                outfile, infile, magic->len*DUMPBLK, ctime(&magic->time));
        !            50:        if (copydump(fr, to))
        !            51:                dumpinval(fr);
        !            52:        copysys();
        !            53:        exit(0);
        !            54: }
        !            55: 
        !            56: /*
        !            57:  * open an output file:
        !            58:  * if it exists and is a directory, make a new file there
        !            59:  * if it doesn't, or is a regular file, just copy it to that name
        !            60:  */
        !            61: 
        !            62: openout(name)
        !            63: char *name;
        !            64: {
        !            65:        int fd;
        !            66:        int i;
        !            67:        static char namebuf[20];
        !            68: 
        !            69:        if ((fd = creat(name, 0666)) >= 0) {
        !            70:                outfile = name;
        !            71:                return (fd);
        !            72:        }
        !            73:        if (errno != EISDIR) {
        !            74:                perror(name);
        !            75:                return (-1);
        !            76:        }
        !            77:        if (chdir(name) < 0) {
        !            78:                perror(name);
        !            79:                return (-1);
        !            80:        }
        !            81:        for (i = 0; ; i++) {
        !            82:                sprintf(namebuf, "z.%d", i);
        !            83:                if (access(namebuf, 0) < 0)
        !            84:                        break;
        !            85:        }
        !            86:        if ((fd = creat(namebuf, 0666)) >= 0) {
        !            87:                outfile = namebuf;
        !            88:                return (fd);
        !            89:        }
        !            90:        perror(namebuf);
        !            91:        return (-1);
        !            92: }
        !            93: 
        !            94: /*
        !            95:  * copy /unix to a place in the directory,
        !            96:  * with a suffix matching the dump we just wrote
        !            97:  * if output was just a filename, don't bother.
        !            98:  * why bother anyway?
        !            99:  */
        !           100: copysys()
        !           101: {
        !           102: }
        !           103: 
        !           104: /*
        !           105:  * open the crash dump
        !           106:  * if no name was given, make a guess:
        !           107:  * try the swap devices in /etc/fstab
        !           108:  * if that doesn't work, guess at the default swap device.
        !           109:  * the dogma is that the name should be supplied anyway,
        !           110:  * and the guesses are for compatibility
        !           111:  */
        !           112: char *swapguess[] = { "/dev/ra01", "/dev/hp01", "/dev/em01", NULL };
        !           113: 
        !           114: int
        !           115: opendump(name)
        !           116: char *name;
        !           117: {
        !           118:        int fd;
        !           119:        register struct fstab *fp;
        !           120:        register int i;
        !           121: 
        !           122:        if (name) {
        !           123:                if ((fd = open(name, 2)) < 0) {
        !           124:                        perror(name);
        !           125:                        return (-1);
        !           126:                }
        !           127:                if ((magic = dumpdata(fd)) == NULL) {
        !           128:                        close(fd);
        !           129:                        return (-1);
        !           130:                }
        !           131:                infile = name;
        !           132:                return (fd);
        !           133:        }
        !           134:        /*
        !           135:         * the hard part
        !           136:         */
        !           137:        printf("I can guess your dump device!\n");
        !           138:        while ((fp = getfsent()) != NULL) {
        !           139:                if (fp->fs_ftype != FSSWAP)
        !           140:                        continue;
        !           141:                if ((fd = open(fp->fs_spec, 2)) < 0)
        !           142:                        continue;
        !           143:                if ((magic = dumpdata(fd)) == NULL) {
        !           144:                        printf("Is it %s?  No.\n", fp->fs_spec);
        !           145:                        close(fd);
        !           146:                        continue;
        !           147:                }
        !           148:                printf("It's %s.\n", fp->fs_spec);
        !           149:                infile = fp->fs_spec;
        !           150:                return (fd);
        !           151:        }
        !           152:        for (i = 0; swapguess[i]; i++) {
        !           153:                if ((fd = open(swapguess[i], 2)) < 0)
        !           154:                        continue;
        !           155:                if ((magic = dumpdata(fd)) == NULL) {
        !           156:                        printf("Is it %s?  No.\n", swapguess[i]);
        !           157:                        close(fd);
        !           158:                        continue;
        !           159:                }
        !           160:                printf("It's %s.\n", swapguess[i]);
        !           161:                infile = swapguess[i];
        !           162:                return (fd);
        !           163:        }
        !           164:        printf("I give up!\n");
        !           165:        return (-1);
        !           166: }
        !           167: 
        !           168: /*
        !           169:  * copy the crash dump
        !           170:  */
        !           171: copydump(fr, to)
        !           172: int fr, to;
        !           173: {
        !           174:        char buf[NBLKS*DUMPBLK];
        !           175:        register int n, r;
        !           176:        register long b;
        !           177: 
        !           178:        lseek(fr, (long)0, 0);
        !           179:        for (b = magic->len * DUMPBLK; b > 0; b -= n) {
        !           180:                if (b > sizeof(buf))
        !           181:                        r = sizeof(buf);
        !           182:                else
        !           183:                        r = b;
        !           184:                if ((n = read(fr, buf, r)) <= 0) {
        !           185:                        if (n < 0)
        !           186:                                perror("read dump");
        !           187:                        else
        !           188:                                fprintf(stderr, "premature EOF on dump: %ld missing\n", b);
        !           189:                        return (1);     /* accept it anyway */
        !           190:                }
        !           191:                if (write(to, buf, n) != n) {
        !           192:                        perror("write dump");
        !           193:                        return (0);
        !           194:                }
        !           195:        }
        !           196:        return (1);
        !           197: }
        !           198: 
        !           199: static char hbuf[DUMPBLK];
        !           200: 
        !           201: /*
        !           202:  * read the header out of a dump,
        !           203:  * and check it for validity
        !           204:  */
        !           205: struct dumpmagic *
        !           206: dumpdata(fd)
        !           207: int fd;
        !           208: {
        !           209:        register struct dumpmagic *mp;
        !           210: 
        !           211:        if (lseek(fd, 0L, 0) < 0)
        !           212:                return (NULL);
        !           213:        if (read(fd, hbuf, sizeof(hbuf)) != sizeof(hbuf))
        !           214:                return (NULL);
        !           215:        mp = (struct dumpmagic *)&hbuf[MAGICADDR];
        !           216:        if (mp->magic != DUMPMAG)
        !           217:                return (NULL);
        !           218:        return (mp);
        !           219: }
        !           220: 
        !           221: /*
        !           222:  * scribble on the header,
        !           223:  * so we won't read this dump again
        !           224:  */
        !           225: dumpinval(fd)
        !           226: int fd;
        !           227: {
        !           228: 
        !           229:        ((struct dumpmagic *)&hbuf[MAGICADDR])->magic = DUMPBAD;
        !           230:        lseek(fd, 0L, 0);
        !           231:        if (write(fd, hbuf, sizeof(hbuf)) != sizeof(hbuf))
        !           232:                perror("taint header");
        !           233: }

unix.superglobalmegacorp.com

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