need init of fromlen once per loop
[unix-history] / usr / src / sbin / savecore / savecore.c
index a9b6a88..2b79d2c 100644 (file)
@@ -1,31 +1,43 @@
 /*
 /*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1980, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
 #ifndef lint
 char copyright[] =
  */
 
 #ifndef lint
 char copyright[] =
-"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+"@(#) Copyright (c) 1980, 1986 The Regents of the University of California.\n\
  All rights reserved.\n";
  All rights reserved.\n";
-#endif not lint
+#endif /* not lint */
 
 #ifndef lint
 
 #ifndef lint
-static char sccsid[] = "@(#)savecore.c 5.6 (Berkeley) %G%";
-#endif not lint
+static char sccsid[] = "@(#)savecore.c 5.17 (Berkeley) %G%";
+#endif /* not lint */
 
 /*
  * savecore
  */
 
 
 /*
  * savecore
  */
 
-#include <stdio.h>
-#include <nlist.h>
 #include <sys/param.h>
 #include <sys/dir.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/file.h>
 #include <sys/param.h>
 #include <sys/dir.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/file.h>
-#include <syslog.h>
+#include <sys/syslog.h>
+#include <stdio.h>
+#include <nlist.h>
+#include <paths.h>
 
 #define        DAY     (60L*60L*24L)
 #define        LEEWAY  (3*DAY)
 
 #define        DAY     (60L*60L*24L)
 #define        LEEWAY  (3*DAY)
@@ -34,8 +46,12 @@ static char sccsid[] = "@(#)savecore.c       5.6 (Berkeley) %G%";
 #ifdef vax
 #define ok(number) ((number)&0x7fffffff)
 #else
 #ifdef vax
 #define ok(number) ((number)&0x7fffffff)
 #else
+#ifdef tahoe
+#define ok(number) ((number)&~0xc0000000)
+#else
 #define ok(number) (number)
 #endif
 #define ok(number) (number)
 #endif
+#endif
 
 struct nlist current_nl[] = {  /* namelist for currently running system */
 #define X_DUMPDEV      0
 
 struct nlist current_nl[] = {  /* namelist for currently running system */
 #define X_DUMPDEV      0
@@ -86,6 +102,9 @@ int  panicstr;
 off_t  lseek();
 off_t  Lseek();
 int    Verbose;
 off_t  lseek();
 off_t  Lseek();
 int    Verbose;
+int    force;
+int    clear;
+extern int errno;
 
 main(argc, argv)
        char **argv;
 
 main(argc, argv)
        char **argv;
@@ -97,14 +116,22 @@ main(argc, argv)
        while (argc > 0 && argv[0][0] == '-') {
                for (cp = &argv[0][1]; *cp; cp++) switch (*cp) {
 
        while (argc > 0 && argv[0][0] == '-') {
                for (cp = &argv[0][1]; *cp; cp++) switch (*cp) {
 
+               case 'f':
+                       force++;
+                       break;
+
                case 'v':
                        Verbose++;
                        break;
 
                case 'v':
                        Verbose++;
                        break;
 
+               case 'c':
+                       clear++;
+                       break;
+
                default:
                usage:
                        fprintf(stderr,
                default:
                usage:
                        fprintf(stderr,
-                           "usage: savecore [-v] dirname [ system ]\n");
+                           "usage: savecore [-f] [-v] dirname [ system ]\n");
                        exit(1);
                }
                argc--, argv++;
                        exit(1);
                }
                argc--, argv++;
@@ -116,7 +143,7 @@ main(argc, argv)
                system = argv[1];
        openlog("savecore", LOG_ODELAY, LOG_AUTH);
        if (access(dirname, W_OK) < 0) {
                system = argv[1];
        openlog("savecore", LOG_ODELAY, LOG_AUTH);
        if (access(dirname, W_OK) < 0) {
-               syslog(LOG_ERR, "%s: %m", dirname);
+               Perror(LOG_ERR, "%s: %m", dirname);
                exit(1);
        }
        read_kmem();
                exit(1);
        }
        read_kmem();
@@ -157,7 +184,7 @@ find_dev(dev, type)
        struct stat statb;
        char *dp;
 
        struct stat statb;
        char *dp;
 
-       strcpy(devname, "/dev/");
+       strcpy(devname, _PATH_DEV);
                if (stat(devname, &statb)) {
                        perror(devname);
                        continue;
                if (stat(devname, &statb)) {
                        perror(devname);
                        continue;
@@ -170,7 +197,7 @@ find_dev(dev, type)
                        return (dp);
                }
        }
                        return (dp);
                }
        }
-       syslog(LOG_ERR, "Can't find device %d/%d\n", major(dev), minor(dev));
+       log(LOG_ERR, "Can't find device %d/%d\n", major(dev), minor(dev));
        exit(1);
        /*NOTREACHED*/
 }
        exit(1);
        /*NOTREACHED*/
 }
@@ -186,8 +213,8 @@ read_kmem()
        char *dump_sys;
        int kmem, i;
        
        char *dump_sys;
        int kmem, i;
        
-       dump_sys = system ? system : "/vmunix";
-       nlist("/vmunix", current_nl);
+       dump_sys = system ? system : _PATH_UNIX;
+       nlist(_PATH_UNIX, current_nl);
        nlist(dump_sys, dump_nl);
        /*
         * Some names we need for the currently running system,
        nlist(dump_sys, dump_nl);
        /*
         * Some names we need for the currently running system,
@@ -199,17 +226,17 @@ read_kmem()
         */
        for (i = 0; cursyms[i] != -1; i++)
                if (current_nl[cursyms[i]].n_value == 0) {
         */
        for (i = 0; cursyms[i] != -1; i++)
                if (current_nl[cursyms[i]].n_value == 0) {
-                       syslog(LOG_ERR, "/vmunix: %s not in namelist",
+                       log(LOG_ERR, "%s: %s not in namelist\n", _PATH_UNIX,
                            current_nl[cursyms[i]].n_name);
                        exit(1);
                }
        for (i = 0; dumpsyms[i] != -1; i++)
                if (dump_nl[dumpsyms[i]].n_value == 0) {
                            current_nl[cursyms[i]].n_name);
                        exit(1);
                }
        for (i = 0; dumpsyms[i] != -1; i++)
                if (dump_nl[dumpsyms[i]].n_value == 0) {
-                       syslog(LOG_ERR, "%s: %s not in namelist", dump_sys,
+                       log(LOG_ERR, "%s: %s not in namelist\n", dump_sys,
                            dump_nl[dumpsyms[i]].n_name);
                        exit(1);
                }
                            dump_nl[dumpsyms[i]].n_name);
                        exit(1);
                }
-       kmem = Open("/dev/kmem", O_RDONLY);
+       kmem = Open(_PATH_KMEM, O_RDONLY);
        Lseek(kmem, (long)current_nl[X_DUMPDEV].n_value, L_SET);
        Read(kmem, (char *)&dumpdev, sizeof (dumpdev));
        Lseek(kmem, (long)current_nl[X_DUMPLO].n_value, L_SET);
        Lseek(kmem, (long)current_nl[X_DUMPDEV].n_value, L_SET);
        Read(kmem, (char *)&dumpdev, sizeof (dumpdev));
        Lseek(kmem, (long)current_nl[X_DUMPLO].n_value, L_SET);
@@ -220,7 +247,7 @@ read_kmem()
        ddname = find_dev(dumpdev, S_IFBLK);
        fp = fdopen(kmem, "r");
        if (fp == NULL) {
        ddname = find_dev(dumpdev, S_IFBLK);
        fp = fdopen(kmem, "r");
        if (fp == NULL) {
-               syslog(LOG_ERR, "Couldn't fdopen kmem");
+               log(LOG_ERR, "Couldn't fdopen kmem\n");
                exit(1);
        }
        if (system)
                exit(1);
        }
        if (system)
@@ -237,16 +264,17 @@ check_kmem()
 
        fp = fopen(ddname, "r");
        if (fp == NULL) {
 
        fp = fopen(ddname, "r");
        if (fp == NULL) {
-               syslog(LOG_ERR, "%s: %m", ddname);
+               Perror(LOG_ERR, "%s: %m", ddname);
                exit(1);
        }
        fseek(fp, (off_t)(dumplo+ok(dump_nl[X_VERSION].n_value)), L_SET);
        fgets(core_vers, sizeof (core_vers), fp);
        fclose(fp);
                exit(1);
        }
        fseek(fp, (off_t)(dumplo+ok(dump_nl[X_VERSION].n_value)), L_SET);
        fgets(core_vers, sizeof (core_vers), fp);
        fclose(fp);
-       if (!eq(vers, core_vers) && system == 0)
-               fprintf(stderr,
-                  "Warning: vmunix version mismatch:\n\t%sand\n\t%s",
-                  vers, core_vers);
+       if (!eq(vers, core_vers) && system == 0) {
+               log(LOG_WARNING, "Warning: %s version mismatch:\n", _PATH_UNIX);
+               log(LOG_WARNING, "\t%s\n", vers);
+               log(LOG_WARNING, "and\t%s\n", core_vers);
+       }
        fp = fopen(ddname, "r");
        fseek(fp, (off_t)(dumplo + ok(dump_nl[X_PANICSTR].n_value)), L_SET);
        fread((char *)&panicstr, sizeof (panicstr), 1, fp);
        fp = fopen(ddname, "r");
        fseek(fp, (off_t)(dumplo + ok(dump_nl[X_PANICSTR].n_value)), L_SET);
        fread((char *)&panicstr, sizeof (panicstr), 1, fp);
@@ -271,7 +299,7 @@ get_crashtime()
        close(dumpfd);
        if (dumptime == 0) {
                if (Verbose)
        close(dumpfd);
        if (dumptime == 0) {
                if (Verbose)
-                       printf("Dump time not found.\n");
+                       printf("Dump time is zero.\n");
                return (0);
        }
        printf("System went down at %s", ctime(&dumptime));
                return (0);
        }
        printf("System went down at %s", ctime(&dumptime));
@@ -302,22 +330,22 @@ check_space()
        struct fs fs;
 
        if (stat(dirname, &dsb) < 0) {
        struct fs fs;
 
        if (stat(dirname, &dsb) < 0) {
-               syslog(LOG_ERR, "%s: %m", dirname);
+               Perror(LOG_ERR, "%s: %m", dirname);
                exit(1);
        }
        ddev = find_dev(dsb.st_dev, S_IFBLK);
        dfd = Open(ddev, O_RDONLY);
                exit(1);
        }
        ddev = find_dev(dsb.st_dev, S_IFBLK);
        dfd = Open(ddev, O_RDONLY);
-       Lseek(dfd, (long)(SBLOCK * DEV_BSIZE), L_SET);
+       Lseek(dfd, SBOFF, L_SET);
        Read(dfd, (char *)&fs, sizeof (fs));
        close(dfd);
        spacefree = freespace(&fs, fs.fs_minfree) * fs.fs_fsize / 1024;
        if (spacefree < read_number("minfree")) {
        Read(dfd, (char *)&fs, sizeof (fs));
        close(dfd);
        spacefree = freespace(&fs, fs.fs_minfree) * fs.fs_fsize / 1024;
        if (spacefree < read_number("minfree")) {
-               syslog(LOG_WARNING, "Dump omitted, not enough space on device");
+               log(LOG_WARNING, "Dump omitted, not enough space on device\n");
                return (0);
        }
        if (freespace(&fs, fs.fs_minfree) < 0)
                return (0);
        }
        if (freespace(&fs, fs.fs_minfree) < 0)
-               syslog(LOG_WARNING,
-                   "Dump performed, but free space threshold crossed");
+               log(LOG_WARNING,
+                   "Dump performed, but free space threshold crossed\n");
        return (1);
 }
 
        return (1);
 }
 
@@ -338,7 +366,7 @@ read_number(fn)
        return (atoi(lin));
 }
 
        return (atoi(lin));
 }
 
-#define        BUFPAGES        (256*1024/NBPG)         /* 1/4 Mb */
+#define        BUFSIZE (256*1024)              /* 1/4 Mb */
 
 save_core()
 {
 
 save_core()
 {
@@ -347,30 +375,30 @@ save_core()
        register int ifd, ofd, bounds;
        register FILE *fp;
 
        register int ifd, ofd, bounds;
        register FILE *fp;
 
-       cp = malloc(BUFPAGES*NBPG);
+       cp = malloc(BUFSIZE);
        if (cp == 0) {
                fprintf(stderr, "savecore: Can't allocate i/o buffer.\n");
                return;
        }
        bounds = read_number("bounds");
        if (cp == 0) {
                fprintf(stderr, "savecore: Can't allocate i/o buffer.\n");
                return;
        }
        bounds = read_number("bounds");
-       ifd = Open(system?system:"/vmunix", O_RDONLY);
-       while((n = Read(ifd, cp, BUFSIZ)) > 0)
+       ifd = Open(system ? system : _PATH_UNIX, O_RDONLY);
+       while((n = Read(ifd, cp, BUFSIZE)) > 0)
                Write(ofd, cp, n);
        close(ifd);
        close(ofd);
        ifd = Open(ddname, O_RDONLY);
        Lseek(ifd, (off_t)(dumplo + ok(dump_nl[X_DUMPSIZE].n_value)), L_SET);
        Read(ifd, (char *)&dumpsize, sizeof (dumpsize));
                Write(ofd, cp, n);
        close(ifd);
        close(ofd);
        ifd = Open(ddname, O_RDONLY);
        Lseek(ifd, (off_t)(dumplo + ok(dump_nl[X_DUMPSIZE].n_value)), L_SET);
        Read(ifd, (char *)&dumpsize, sizeof (dumpsize));
-       sprintf(cp, "vmcore.%d", bounds);
+       (void)sprintf(cp, "vmcore.%d", bounds);
        ofd = Create(path(cp), 0644);
        Lseek(ifd, (off_t)dumplo, L_SET);
        ofd = Create(path(cp), 0644);
        Lseek(ifd, (off_t)dumplo, L_SET);
-       printf("Saving %d bytes of image in vmcore.%d\n", NBPG*dumpsize,
-               bounds);
+       log(LOG_NOTICE, "Saving %d bytes of image in vmcore.%d\n",
+           NBPG*dumpsize, bounds);
        while (dumpsize > 0) {
                n = Read(ifd, cp,
                    (dumpsize > BUFPAGES ? BUFPAGES : dumpsize) * NBPG);
                if (n == 0) {
        while (dumpsize > 0) {
                n = Read(ifd, cp,
                    (dumpsize > BUFPAGES ? BUFPAGES : dumpsize) * NBPG);
                if (n == 0) {
-                       printf("WARNING: core may be incomplete\n");
+                       log(LOG_WARNING, "WARNING: vmcore may be incomplete\n");
                        break;
                }
                Write(ofd, cp, n);
                        break;
                }
                Write(ofd, cp, n);
@@ -384,32 +412,6 @@ save_core()
        free(cp);
 }
 
        free(cp);
 }
 
-char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
-char *months[] = {
-       "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
-       "Oct", "Nov", "Dec"
-};
-
-log_entry()
-{
-       FILE *fp;
-       struct tm *tm, *localtime();
-
-       fp = fopen("/usr/adm/shutdownlog", "a");
-       if (fp == 0)
-               return;
-       tm = localtime(&now);
-       fseek(fp, 0L, L_XTND);
-       fprintf(fp, "%02d:%02d  %s %s %2d, %4d.  Reboot", tm->tm_hour,
-               tm->tm_min, days[tm->tm_wday], months[tm->tm_mon],
-               tm->tm_mday, tm->tm_year + 1900);
-       if (panicstr)
-               fprintf(fp, " after panic: %s\n", panic_mesg);
-       else
-               putc('\n', fp);
-       fclose(fp);
-}
-
 /*
  * Versions of std routines that exit on error.
  */
 /*
  * Versions of std routines that exit on error.
  */
@@ -421,7 +423,7 @@ Open(name, rw)
 
        fd = open(name, rw);
        if (fd < 0) {
 
        fd = open(name, rw);
        if (fd < 0) {
-               syslog(LOG_ERR, "%s: %m", name);
+               Perror(LOG_ERR, "%s: %m", name);
                exit(1);
        }
        return (fd);
                exit(1);
        }
        return (fd);
@@ -435,7 +437,7 @@ Read(fd, buff, size)
 
        ret = read(fd, buff, size);
        if (ret < 0) {
 
        ret = read(fd, buff, size);
        if (ret < 0) {
-               syslog(LOG_ERR, "read: %m");
+               Perror(LOG_ERR, "read: %m");
                exit(1);
        }
        return (ret);
                exit(1);
        }
        return (ret);
@@ -450,7 +452,7 @@ Lseek(fd, off, flag)
 
        ret = lseek(fd, off, flag);
        if (ret == -1) {
 
        ret = lseek(fd, off, flag);
        if (ret == -1) {
-               syslog(LOG_ERR, "lseek: %m");
+               Perror(LOG_ERR, "lseek: %m");
                exit(1);
        }
        return (ret);
                exit(1);
        }
        return (ret);
@@ -464,7 +466,7 @@ Create(file, mode)
 
        fd = creat(file, mode);
        if (fd < 0) {
 
        fd = creat(file, mode);
        if (fd < 0) {
-               syslog(LOG_ERR, "%s: %m", file);
+               Perror(LOG_ERR, "%s: %m", file);
                exit(1);
        }
        return (fd);
                exit(1);
        }
        return (fd);
@@ -476,7 +478,27 @@ Write(fd, buf, size)
 {
 
        if (write(fd, buf, size) < size) {
 {
 
        if (write(fd, buf, size) < size) {
-               syslog(LOG_ERR, "write: %m");
+               Perror(LOG_ERR, "write: %m");
                exit(1);
        }
 }
                exit(1);
        }
 }
+
+log(level, msg, a1, a2)
+       int level;
+       char *msg;
+{
+
+       fprintf(stderr, msg, a1, a2);
+       syslog(level, msg, a1, a2);
+}
+
+Perror(level, msg, s)
+       int level;
+       char *msg;
+{
+       int oerrno = errno;
+       
+       perror(s);
+       errno = oerrno;
+       syslog(level, msg, s);
+}