Annotation of researchv10no/cmd/savecore.c, revision 1.1.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.