Annotation of 43BSDReno/sbin/dump/dumpoptr.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980, 1988 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: static char sccsid[] = "@(#)dumpoptr.c 5.3 (Berkeley) 2/15/90";
        !             9: #endif not lint
        !            10: 
        !            11: #include "dump.h"
        !            12: #include <sys/time.h>
        !            13: #include "pathnames.h"
        !            14: 
        !            15: /*
        !            16:  *     This is from /usr/include/grp.h
        !            17:  *     That defined struct group, which conflicts
        !            18:  *     with the struct group defined in param.h
        !            19:  */
        !            20: struct Group { /* see getgrent(3) */
        !            21:        char    *gr_name;
        !            22:        char    *gr_passwd;
        !            23:        int     gr_gid;
        !            24:        char    **gr_mem;
        !            25: };
        !            26: struct Group *getgrnam();
        !            27: /*
        !            28:  *     Query the operator; This previously-fascist piece of code
        !            29:  *     no longer requires an exact response.
        !            30:  *     It is intended to protect dump aborting by inquisitive
        !            31:  *     people banging on the console terminal to see what is
        !            32:  *     happening which might cause dump to croak, destroying
        !            33:  *     a large number of hours of work.
        !            34:  *
        !            35:  *     Every 2 minutes we reprint the message, alerting others
        !            36:  *     that dump needs attention.
        !            37:  */
        !            38: int    timeout;
        !            39: char   *attnmessage;           /* attention message */
        !            40: query(question)
        !            41:        char    *question;
        !            42: {
        !            43:        char    replybuffer[64];
        !            44:        int     back;
        !            45:        FILE    *mytty;
        !            46: 
        !            47:        if ( (mytty = fopen(_PATH_TTY, "r")) == NULL){
        !            48:                msg("fopen on %s fails\n", _PATH_TTY);
        !            49:                abort();
        !            50:        }
        !            51:        attnmessage = question;
        !            52:        timeout = 0;
        !            53:        alarmcatch();
        !            54:        for(;;){
        !            55:                if ( fgets(replybuffer, 63, mytty) == NULL){
        !            56:                        if (ferror(mytty)){
        !            57:                                clearerr(mytty);
        !            58:                                continue;
        !            59:                        }
        !            60:                } else if (replybuffer[0] == 'y' || replybuffer[0] == 'Y') {
        !            61:                                back = 1;
        !            62:                                goto done;
        !            63:                } else if (replybuffer[0] == 'n' || replybuffer[0] == 'N') {
        !            64:                                back = 0;
        !            65:                                goto done;
        !            66:                } else {
        !            67:                        fprintf(stderr, "  DUMP: \"Yes\" or \"No\"?\n");
        !            68:                        fprintf(stderr,"  DUMP: %s: (\"yes\" or \"no\") ",
        !            69:                            question);
        !            70:                }
        !            71:        }
        !            72:     done:
        !            73:        /*
        !            74:         *      Turn off the alarm, and reset the signal to trap out..
        !            75:         */
        !            76:        alarm(0);
        !            77:        if (signal(SIGALRM, sigalrm) == SIG_IGN)
        !            78:                signal(SIGALRM, SIG_IGN);
        !            79:        fclose(mytty);
        !            80:        return(back);
        !            81: }
        !            82: 
        !            83: char lastmsg[100];
        !            84: 
        !            85: /*
        !            86:  *     Alert the console operator, and enable the alarm clock to
        !            87:  *     sleep for 2 minutes in case nobody comes to satisfy dump
        !            88:  */
        !            89: alarmcatch()
        !            90: {
        !            91:        if (notify == 0) {
        !            92:                if (timeout == 0)
        !            93:                        fprintf(stderr,"  DUMP: %s: (\"yes\" or \"no\") ",
        !            94:                            attnmessage);
        !            95:                else
        !            96:                        msgtail("\7\7");
        !            97:        } else {
        !            98:                if (timeout) {
        !            99:                        msgtail("\n");
        !           100:                        broadcast("");          /* just print last msg */
        !           101:                }
        !           102:                fprintf(stderr,"  DUMP: %s: (\"yes\" or \"no\") ",
        !           103:                    attnmessage);
        !           104:        }
        !           105:        signal(SIGALRM, alarmcatch);
        !           106:        alarm(120);
        !           107:        timeout = 1;
        !           108: }
        !           109: /*
        !           110:  *     Here if an inquisitive operator interrupts the dump program
        !           111:  */
        !           112: interrupt()
        !           113: {
        !           114:        msg("Interrupt received.\n");
        !           115:        if (query("Do you want to abort dump?"))
        !           116:                dumpabort();
        !           117: }
        !           118: 
        !           119: /*
        !           120:  *     The following variables and routines manage alerting
        !           121:  *     operators to the status of dump.
        !           122:  *     This works much like wall(1) does.
        !           123:  */
        !           124: struct Group *gp;
        !           125: 
        !           126: /*
        !           127:  *     Get the names from the group entry "operator" to notify.
        !           128:  */    
        !           129: set_operators()
        !           130: {
        !           131:        if (!notify)            /*not going to notify*/
        !           132:                return;
        !           133:        gp = getgrnam(OPGRENT);
        !           134:        endgrent();
        !           135:        if (gp == (struct Group *)0){
        !           136:                msg("No group entry for %s.\n",
        !           137:                        OPGRENT);
        !           138:                notify = 0;
        !           139:                return;
        !           140:        }
        !           141: }
        !           142: 
        !           143: struct tm *localtime();
        !           144: struct tm *localclock;
        !           145: 
        !           146: /*
        !           147:  *     We fork a child to do the actual broadcasting, so
        !           148:  *     that the process control groups are not messed up
        !           149:  */
        !           150: broadcast(message)
        !           151:        char    *message;
        !           152: {
        !           153:        time_t          clock;
        !           154:        FILE    *f_utmp;
        !           155:        struct  utmp    utmp;
        !           156:        int     nusers;
        !           157:        char    **np;
        !           158:        int     pid, s;
        !           159: 
        !           160:        switch (pid = fork()) {
        !           161:        case -1:
        !           162:                return;
        !           163:        case 0:
        !           164:                break;
        !           165:        default:
        !           166:                while (wait(&s) != pid)
        !           167:                        continue;
        !           168:                return;
        !           169:        }
        !           170: 
        !           171:        if (!notify || gp == 0)
        !           172:                exit(0);
        !           173:        clock = time(0);
        !           174:        localclock = localtime(&clock);
        !           175: 
        !           176:        if((f_utmp = fopen(_PATH_UTMP, "r")) == NULL) {
        !           177:                msg("Cannot open %s\n", _PATH_UTMP);
        !           178:                return;
        !           179:        }
        !           180: 
        !           181:        nusers = 0;
        !           182:        while (!feof(f_utmp)){
        !           183:                if (fread(&utmp, sizeof (struct utmp), 1, f_utmp) != 1)
        !           184:                        break;
        !           185:                if (utmp.ut_name[0] == 0)
        !           186:                        continue;
        !           187:                nusers++;
        !           188:                for (np = gp->gr_mem; *np; np++){
        !           189:                        if (strncmp(*np, utmp.ut_name, sizeof(utmp.ut_name)) != 0)
        !           190:                                continue;
        !           191:                        /*
        !           192:                         *      Do not send messages to operators on dialups
        !           193:                         */
        !           194:                        if (strncmp(utmp.ut_line, DIALUP, strlen(DIALUP)) == 0)
        !           195:                                continue;
        !           196: #ifdef DEBUG
        !           197:                        msg("Message to %s at %s\n",
        !           198:                                utmp.ut_name, utmp.ut_line);
        !           199: #endif DEBUG
        !           200:                        sendmes(utmp.ut_line, message);
        !           201:                }
        !           202:        }
        !           203:        fclose(f_utmp);
        !           204:        Exit(0);        /* the wait in this same routine will catch this */
        !           205:        /* NOTREACHED */
        !           206: }
        !           207: 
        !           208: sendmes(tty, message)
        !           209:        char *tty, *message;
        !           210: {
        !           211:        char t[50], buf[BUFSIZ];
        !           212:        register char *cp;
        !           213:        int lmsg = 1;
        !           214:        FILE *f_tty;
        !           215: 
        !           216:        strcpy(t, _PATH_DEV);
        !           217:        strcat(t, tty);
        !           218: 
        !           219:        if((f_tty = fopen(t, "w")) != NULL) {
        !           220:                setbuf(f_tty, buf);
        !           221:                fprintf(f_tty, "\n\07\07\07Message from the dump program to all operators at %d:%02d ...\r\n\n  DUMP: NEEDS ATTENTION: "
        !           222:                       ,localclock->tm_hour
        !           223:                       ,localclock->tm_min);
        !           224:                for (cp = lastmsg; ; cp++) {
        !           225:                        if (*cp == '\0') {
        !           226:                                if (lmsg) {
        !           227:                                        cp = message;
        !           228:                                        if (*cp == '\0')
        !           229:                                                break;
        !           230:                                        lmsg = 0;
        !           231:                                } else
        !           232:                                        break;
        !           233:                        }
        !           234:                        if (*cp == '\n')
        !           235:                                putc('\r', f_tty);
        !           236:                        putc(*cp, f_tty);
        !           237:                }
        !           238:                fclose(f_tty);
        !           239:        }
        !           240: }
        !           241: 
        !           242: /*
        !           243:  *     print out an estimate of the amount of time left to do the dump
        !           244:  */
        !           245: 
        !           246: time_t tschedule = 0;
        !           247: 
        !           248: timeest()
        !           249: {
        !           250:        time_t  tnow, deltat;
        !           251: 
        !           252:        time (&tnow);
        !           253:        if (tnow >= tschedule){
        !           254:                tschedule = tnow + 300;
        !           255:                if (blockswritten < 500)
        !           256:                        return; 
        !           257:                deltat = tstart_writing - tnow +
        !           258:                        (((1.0*(tnow - tstart_writing))/blockswritten) * esize);
        !           259:                msg("%3.2f%% done, finished in %d:%02d\n",
        !           260:                        (blockswritten*100.0)/esize,
        !           261:                        deltat/3600, (deltat%3600)/60);
        !           262:        }
        !           263: }
        !           264: 
        !           265: int blocksontape()
        !           266: {
        !           267:        /*
        !           268:         *      esize: total number of blocks estimated over all reels
        !           269:         *      blockswritten:  blocks actually written, over all reels
        !           270:         *      etapes: estimated number of tapes to write
        !           271:         *
        !           272:         *      tsize:  blocks can write on this reel
        !           273:         *      asize:  blocks written on this reel
        !           274:         *      tapeno: number of tapes written so far
        !           275:         */
        !           276:        if (tapeno == etapes)
        !           277:                return(esize - (etapes - 1)*tsize);
        !           278:        return(tsize);
        !           279: }
        !           280: 
        !           281:        /* VARARGS1 */
        !           282:        /* ARGSUSED */
        !           283: msg(fmt, a1, a2, a3, a4, a5)
        !           284:        char    *fmt;
        !           285:        int     a1, a2, a3, a4, a5;
        !           286: {
        !           287:        fprintf(stderr,"  DUMP: ");
        !           288: #ifdef TDEBUG
        !           289:        fprintf(stderr,"pid=%d ", getpid());
        !           290: #endif
        !           291:        fprintf(stderr, fmt, a1, a2, a3, a4, a5);
        !           292:        fflush(stdout);
        !           293:        fflush(stderr);
        !           294:        sprintf(lastmsg, fmt, a1, a2, a3, a4, a5);
        !           295: }
        !           296: 
        !           297:        /* VARARGS1 */
        !           298:        /* ARGSUSED */
        !           299: msgtail(fmt, a1, a2, a3, a4, a5)
        !           300:        char    *fmt;
        !           301:        int     a1, a2, a3, a4, a5;
        !           302: {
        !           303:        fprintf(stderr, fmt, a1, a2, a3, a4, a5);
        !           304: }
        !           305: /*
        !           306:  *     Tell the operator what has to be done;
        !           307:  *     we don't actually do it
        !           308:  */
        !           309: 
        !           310: struct fstab *
        !           311: allocfsent(fs)
        !           312:        register struct fstab *fs;
        !           313: {
        !           314:        register struct fstab *new;
        !           315:        register char *cp;
        !           316:        char *malloc();
        !           317: 
        !           318:        new = (struct fstab *)malloc(sizeof (*fs));
        !           319:        cp = malloc(strlen(fs->fs_file) + 1);
        !           320:        strcpy(cp, fs->fs_file);
        !           321:        new->fs_file = cp;
        !           322:        cp = malloc(strlen(fs->fs_type) + 1);
        !           323:        strcpy(cp, fs->fs_type);
        !           324:        new->fs_type = cp;
        !           325:        cp = malloc(strlen(fs->fs_spec) + 1);
        !           326:        strcpy(cp, fs->fs_spec);
        !           327:        new->fs_spec = cp;
        !           328:        new->fs_passno = fs->fs_passno;
        !           329:        new->fs_freq = fs->fs_freq;
        !           330:        return (new);
        !           331: }
        !           332: 
        !           333: struct pfstab {
        !           334:        struct  pfstab *pf_next;
        !           335:        struct  fstab *pf_fstab;
        !           336: };
        !           337: 
        !           338: static struct pfstab *table = NULL;
        !           339: 
        !           340: getfstab()
        !           341: {
        !           342:        register struct fstab *fs;
        !           343:        register struct pfstab *pf;
        !           344: 
        !           345:        if (setfsent() == 0) {
        !           346:                msg("Can't open %s for dump table information.\n", _PATH_FSTAB);
        !           347:                return;
        !           348:        }
        !           349:        while (fs = getfsent()) {
        !           350:                if (strcmp(fs->fs_type, FSTAB_RW) &&
        !           351:                    strcmp(fs->fs_type, FSTAB_RO) &&
        !           352:                    strcmp(fs->fs_type, FSTAB_RQ))
        !           353:                        continue;
        !           354:                fs = allocfsent(fs);
        !           355:                pf = (struct pfstab *)malloc(sizeof (*pf));
        !           356:                pf->pf_fstab = fs;
        !           357:                pf->pf_next = table;
        !           358:                table = pf;
        !           359:        }
        !           360:        endfsent();
        !           361: }
        !           362: 
        !           363: /*
        !           364:  * Search in the fstab for a file name.
        !           365:  * This file name can be either the special or the path file name.
        !           366:  *
        !           367:  * The entries in the fstab are the BLOCK special names, not the
        !           368:  * character special names.
        !           369:  * The caller of fstabsearch assures that the character device
        !           370:  * is dumped (that is much faster)
        !           371:  *
        !           372:  * The file name can omit the leading '/'.
        !           373:  */
        !           374: struct fstab *
        !           375: fstabsearch(key)
        !           376:        char *key;
        !           377: {
        !           378:        register struct pfstab *pf;
        !           379:        register struct fstab *fs;
        !           380:        char *rawname();
        !           381: 
        !           382:        if (table == NULL)
        !           383:                return ((struct fstab *)0);
        !           384:        for (pf = table; pf; pf = pf->pf_next) {
        !           385:                fs = pf->pf_fstab;
        !           386:                if (strcmp(fs->fs_file, key) == 0)
        !           387:                        return (fs);
        !           388:                if (strcmp(fs->fs_spec, key) == 0)
        !           389:                        return (fs);
        !           390:                if (strcmp(rawname(fs->fs_spec), key) == 0)
        !           391:                        return (fs);
        !           392:                if (key[0] != '/'){
        !           393:                        if (*fs->fs_spec == '/' &&
        !           394:                            strcmp(fs->fs_spec + 1, key) == 0)
        !           395:                                return (fs);
        !           396:                        if (*fs->fs_file == '/' &&
        !           397:                            strcmp(fs->fs_file + 1, key) == 0)
        !           398:                                return (fs);
        !           399:                }
        !           400:        }
        !           401:        return (0);
        !           402: }
        !           403: 
        !           404: /*
        !           405:  *     Tell the operator what to do
        !           406:  */
        !           407: lastdump(arg)
        !           408:        char    arg;            /* w ==> just what to do; W ==> most recent dumps */
        !           409: {
        !           410:                        char    *lastname;
        !           411:                        char    *date;
        !           412:        register        int     i;
        !           413:                        time_t  tnow;
        !           414:        register        struct  fstab   *dt;
        !           415:                        int     dumpme;
        !           416:        register        struct  idates  *itwalk;
        !           417: 
        !           418:        int     idatesort();
        !           419: 
        !           420:        time(&tnow);
        !           421:        getfstab();             /* /etc/fstab input */
        !           422:        inititimes();           /* /etc/dumpdates input */
        !           423:        qsort(idatev, nidates, sizeof(struct idates *), idatesort);
        !           424: 
        !           425:        if (arg == 'w')
        !           426:                fprintf(stdout, "Dump these file systems:\n");
        !           427:        else
        !           428:                fprintf(stdout, "Last dump(s) done (Dump '>' file systems):\n");
        !           429:        lastname = "??";
        !           430:        ITITERATE(i, itwalk){
        !           431:                if (strncmp(lastname, itwalk->id_name, sizeof(itwalk->id_name)) == 0)
        !           432:                        continue;
        !           433:                date = (char *)ctime(&itwalk->id_ddate);
        !           434:                date[16] = '\0';                /* blast away seconds and year */
        !           435:                lastname = itwalk->id_name;
        !           436:                dt = fstabsearch(itwalk->id_name);
        !           437:                dumpme = (  (dt != 0)
        !           438:                         && (dt->fs_freq != 0)
        !           439:                         && (itwalk->id_ddate < tnow - (dt->fs_freq*DAY)));
        !           440:                if ( (arg != 'w') || dumpme)
        !           441:                  fprintf(stdout,"%c %8s\t(%6s) Last dump: Level %c, Date %s\n",
        !           442:                        dumpme && (arg != 'w') ? '>' : ' ',
        !           443:                        itwalk->id_name,
        !           444:                        dt ? dt->fs_file : "",
        !           445:                        itwalk->id_incno,
        !           446:                        date
        !           447:                    );
        !           448:        }
        !           449: }
        !           450: 
        !           451: int    idatesort(p1, p2)
        !           452:        struct  idates  **p1, **p2;
        !           453: {
        !           454:        int     diff;
        !           455: 
        !           456:        diff = strncmp((*p1)->id_name, (*p2)->id_name, sizeof((*p1)->id_name));
        !           457:        if (diff == 0)
        !           458:                return ((*p2)->id_ddate - (*p1)->id_ddate);
        !           459:        else
        !           460:                return (diff);
        !           461: }
        !           462: 
        !           463: int max(a,b)
        !           464:        int a, b;
        !           465: {
        !           466:        return(a>b?a:b);
        !           467: }
        !           468: int min(a,b)
        !           469:        int a, b;
        !           470: {
        !           471:        return(a<b?a:b);
        !           472: }

unix.superglobalmegacorp.com

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