# 2.11BSD#431 - /usr/src/old/dump/dumpoptr.c

##### Functions

    alarmcatch        X
    blocksontape      X
    broadcast         X
    idatesort         X
    interrupt         X
    lastdump          X
    max               X
    min               X
    msg               X
    msgtail           X
    query             X
    sendmes           X
    set_operators     X
    timeest           X

##### Variables

    attnmessage       X
    gp                X
    localclock        X
    timeout           X
    tschedule         X

       1: static  char *sccsid = "@(#)dumpoptr.c	1.4.1 (2.11BSD) 1996/11/17";
       2: #include "dump.h"
       3:
       4: struct  group *getgrnam();
       5: /*
       6:  *	Query the operator; This fascist piece of code requires
       7:  *	an exact response.
       8:  *	It is intended to protect dump aborting by inquisitive
       9:  *	people banging on the console terminal to see what is
      10:  *	happening which might cause dump to croak, destroying
      11:  *	a large number of hours of work.
      12:  *
      13:  *	Every 2 minutes we reprint the message, alerting others
      14:  *	that dump needs attention.
      15:  */
      16: int timeout;
      17: char    *attnmessage;       /* attemtion message */
      18: query(question)
      19:     char    *question;
      20: {
      21:     char    replybuffer[64];
      22:     int back;
      23:     FILE    *mytty;
      24:
      25:     if ( (mytty = fopen("/dev/tty", "r")) == NULL){
      26:         msg("fopen on /dev/tty fails\n");
      27:         abort();
      28:     }
      29:     attnmessage = question;
      30:     timeout = 0;
      31:     alarmcatch();
      32:     for(;;){
      33:         if ( fgets(replybuffer, 63, mytty) == NULL){
      34:             if (ferror(mytty)){
      35:                 clearerr(mytty);
      36:                 continue;
      37:             }
      38:         } else if ( (strcmp(replybuffer, "yes\n") == 0) ||
      39:                 (strcmp(replybuffer, "Yes\n") == 0)){
      40:                 back = 1;
      41:                 goto done;
      42:         } else if ( (strcmp(replybuffer, "no\n") == 0) ||
      43:                 (strcmp(replybuffer, "No\n") == 0)){
      44:                 back = 0;
      45:                 goto done;
      46:         } else {
      47:             msg("\"Yes\" or \"No\"?\n");
      48:             alarmcatch();
      49:         }
      50:     }
      51:     done:
      52:     /*
      53: 	 *	Turn off the alarm, and reset the signal to trap out..
      54: 	 */
      55:     alarm(0);
      56:     if (signal(SIGALRM, sigalrm) == SIG_IGN)
      57:         signal(SIGALRM, SIG_IGN);
      58:     fclose(mytty);
      59:     return(back);
      60: }
      61: /*
      62:  *	Alert the console operator, and enable the alarm clock to
      63:  *	sleep for 2 minutes in case nobody comes to satisfy dump
      64:  */
      65: alarmcatch()
      66: {
      67:     if (timeout)
      68:         msgtail("\n");
      69:     msg("NEEDS ATTENTION: %s: (\"yes\" or \"no\") ",
      70:         attnmessage);
      71:     signal(SIGALRM, alarmcatch);
      72:     alarm(120);
      73:     timeout = 1;
      74: }
      75: /*
      76:  *	Here if an inquisitive operator interrupts the dump program
      77:  */
      78: interrupt()
      79: {
      80:     msg("Interrupt received.\n");
      81:     if (query("Do you want to abort dump?"))
      82:         dumpabort();
      83:     signal(SIGINT, interrupt);
      84: }
      85:
      86: /*
      87:  *	The following variables and routines manage alerting
      88:  *	operators to the status of dump.
      89:  *	This works much like wall(1) does.
      90:  */
      91: struct  group *gp;
      92:
      93: /*
      94:  *	Get the names from the group entry "operator" to notify.
      95:  */
      96: set_operators()
      97: {
      98:     if (!notify)        /*not going to notify*/
      99:         return;
     100:     gp = getgrnam(OPGRENT);
     101:     endgrent();
     102:     if (gp == (struct group *)0){
     103:         msg("No entry in /etc/group for %s.\n",
     104:             OPGRENT);
     105:         notify = 0;
     106:         return;
     107:     }
     108: }
     109:
     110: struct tm *localtime();
     111: struct tm *localclock;
     112:
     113: /*
     114:  *	We fork a child to do the actual broadcasting, so
     115:  *	that the process control groups are not messed up
     116:  */
     117: broadcast(message)
     118:     char    *message;
     119: {
     120:     time_t      clock;
     121:     FILE    *f_utmp;
     122:     struct  utmp    utmp;
     123:     char    **np;
     124:     int pid, s;
     125:
     126:     switch (pid = fork()) {
     127:     case -1:
     128:         return;
     129:     case 0:
     130:         break;
     131:     default:
     132:         while (wait(&s) != pid)
     133:             continue;
     134:         return;
     135:     }
     136:
     137:     if (!notify || gp == 0)
     138:         exit(0);
     139:     clock = time((time_t *)0);
     140:     localclock = localtime(&clock);
     141:
     142:     if((f_utmp = fopen(_PATH_UTMP, "r")) == NULL) {
     143:         msg("Cannot open 'utmp'\n");
     144:         return;
     145:     }
     146:
     147:     while (!feof(f_utmp)){
     148:         if (fread((char *)&utmp, sizeof (struct utmp), 1, f_utmp) != 1)
     149:             break;
     150:         if (utmp.ut_name[0] == 0)
     151:             continue;
     152:         for (np = gp->gr_mem; *np; np++){
     153:             if (strncmp(*np, utmp.ut_name, sizeof(utmp.ut_name)) != 0)
     154:                 continue;
     155:             /*
     156: 			 *	Do not send messages to operators on dialups
     157: 			 */
     158:             if (strncmp(utmp.ut_line, DIALUP, strlen(DIALUP)) == 0)
     159:                 continue;
     160: #ifdef DEBUG
     161:             msg("Message to %s at %s\n",
     162:                 utmp.ut_name, utmp.ut_line);
     163: #endif DEBUG
     164:             sendmes(utmp.ut_line, message);
     165:         }
     166:     }
     167:     fclose(f_utmp);
     168:     Exit(0);    /* the wait in this same routine will catch this */
     169:     /* NOTREACHED */
     170: }
     171:
     172: sendmes(tty, message)
     173: char *tty, *message;
     174: {
     175:     char t[50], buf[BUFSIZ];
     176:     register char *cp;
     177:     register int c, ch;
     178:     int msize;
     179:     FILE *f_tty;
     180:
     181:     msize = strlen(message);
     182:     strcpy(t, "/dev/");
     183:     strcat(t, tty);
     184:
     185:     if((f_tty = fopen(t, "w")) != NULL) {
     186:         setbuf(f_tty, buf);
     187:         fprintf(f_tty, "\n\007\007\007Message from the dump program to all operators at %d:%02d ...\r\n\n"
     188:                ,localclock->tm_hour
     189:                ,localclock->tm_min);
     190:         for (cp = message, c = msize; c-- > 0; cp++) {
     191:             ch = *cp;
     192:             if (ch == '\n')
     193:                 putc('\r', f_tty);
     194:             putc(ch, f_tty);
     195:         }
     196:         fclose(f_tty);
     197:     }
     198: }
     199:
     200: /*
     201:  *	print out an estimate of the amount of time left to do the dump
     202:  */
     203:
     204: time_t  tschedule = 0;
     205:
     206: timeest()
     207: {
     208:     time_t  tnow, deltat;
     209:     long    pleft;
     210:     char buf[BUFSIZ];
     211:
     212:     time (&tnow);
     213:     if (tnow >= tschedule){
     214:         tschedule = tnow + 300;
     215:         if (blockswritten < 500L)
     216:             return;
     217: /*
     218: 			/				    \
     219: 			|/ estimated blocks \		    |
     220: 	delta time =	||----------------  | X time so far |  - time so far
     221: 			|\ blocks thus far  /		    |
     222: 			\				    /
     223: */
     224:         pleft  = ((100 * esize)/blockswritten) - 100;
     225:         deltat = (time_t) (tnow - tstart_writing) * pleft;
     226:         deltat = deltat/100;    /* scale back down */
     227:         sprintf(buf,"%3.2f%%%% done, finished in %d:%02d\n",
     228:             (float) (blockswritten*100.0)/esize,
     229:             (int)(deltat/3600L), (int)((deltat%3600L)/60L));
     230:         msg(buf);
     231:     }
     232: }
     233:
     234: int blocksontape()
     235: {
     236:     /*
     237: 	 *	esize: total number of blocks estimated over all reels
     238: 	 *	blockswritten:	blocks actually written, over all reels
     239: 	 *	etapes:	estimated number of tapes to write
     240: 	 *
     241: 	 *	tsize:	blocks can write on this reel
     242: 	 *	asize:	blocks written on this reel
     243: 	 *	tapeno:	number of tapes written so far
     244: 	 */
     245:     if (tapeno == etapes)
     246:         return(esize - (etapes - 1)*tsize);
     247:     return(tsize);
     248: }
     249:
     250:     /* VARARGS1 */
     251:     /* ARGSUSED */
     252: msg(fmt, a1, a2, a3, a4, a5)
     253:     char    *fmt;
     254: {
     255:     fprintf(stderr,"  DUMP: ");
     256: #ifdef TDEBUG
     257:     fprintf(stderr,"pid=%d ", getpid());
     258: #endif
     259:     fprintf(stderr, fmt, a1, a2, a3, a4, a5);
     260:     fflush(stdout);
     261:     fflush(stderr);
     262: }
     263:
     264:     /* VARARGS1 */
     265:     /* ARGSUSED */
     266: msgtail(fmt, a1, a2, a3, a4, a5)
     267:     char    *fmt;
     268: {
     269:     fprintf(stderr, fmt, a1, a2, a3, a4, a5);
     270: }
     271:
     272: /*
     273:  *	Tell the operator what has to be done.
     274:  */
     275: lastdump(arg)
     276:     char    arg;    /* w ==> just what to do; W ==> most recent dumps */
     277: {
     278:             char    *lastname;
     279:             char    *date;
     280:     register    int i;
     281:             time_t  tnow;
     282:     register    struct  fstab   *dt;
     283:             int dumpme;
     284:     register    struct  idates  *itwalk;
     285:
     286:     int idatesort();
     287:
     288:     time(&tnow);
     289:     inititimes();       /* /etc/dumpdates input */
     290:     qsort(idatev, nidates, sizeof(struct idates *), idatesort);
     291:
     292:     if (arg == 'w')
     293:         fprintf(stdout, "Dump these file systems:\n");
     294:     else
     295:         fprintf(stdout, "Last dump(s) done (Dump '>' file systems):\n");
     296:     lastname = "??";
     297:     ITITERATE(i, itwalk){
     298:         if (strncmp(lastname, itwalk->id_name, sizeof(itwalk->id_name)) == 0)
     299:             continue;
     300:         date = (char *)ctime(&itwalk->id_ddate);
     301:         date[16] = '\0';    /* blast away seconds and year */
     302:         lastname = itwalk->id_name;
     303:         dt = getfsspec(deraw(itwalk->id_name));
     304:         dumpme = (  (dt != 0)
     305:              && (dt->fs_freq != 0)
     306:              && (itwalk->id_ddate < tnow - (dt->fs_freq*DAY)));
     307:         if ( (arg != 'w') || dumpme)
     308:           fprintf(stdout,"%c %8s\t(%6s) Last dump: Level %c, Date %s\n",
     309:             dumpme && (arg != 'w') ? '>' : ' ',
     310:             itwalk->id_name,
     311:             dt ? dt->fs_file : 0,
     312:             itwalk->id_incno,
     313:             date
     314:             );
     315:     }
     316: }
     317:
     318: int idatesort(p1, p2)
     319:     struct  idates  **p1, **p2;
     320: {
     321:     int diff;
     322:
     323:     diff = strncmp((*p1)->id_name, (*p2)->id_name, sizeof((*p1)->id_name));
     324:     if (diff == 0)
     325:         if ((*p2)->id_ddate > (*p1)->id_ddate)
     326:             return (1);
     327:         else
     328:             if ((*p2)->id_ddate == (*p1)->id_ddate)
     329:                 return (0);
     330:             else
     331:                 return (-1);
     332:     else
     333:         return (diff);
     334: }
     335:
     336: int max(a,b)
     337: {
     338:     return(a>b?a:b);
     339: }
     340: int min(a,b)
     341: {
     342:     return(a<b?a:b);
     343: }

#### Defined functions

alarmcatch defined in line 65; used 3 times

- in line 31, 48, 71

blocksontape defined in line 234; never used
broadcast defined in line 117; used 4 times

- in /usr/src/old/dump/dumpmain.c line 205
- in /usr/src/old/dump/dumptape.c line 61, 115
- in /usr/src/old/dump/dumptraverse.c line 259

idatesort defined in line 318; used 2 times

- in line 286-290(2)

interrupt defined in line 78; used 4 times

- in line 83
- in /usr/src/old/dump/dump.h line 79
- in /usr/src/old/dump/dumptape.c line 145, 154

lastdump defined in line 275; used 2 times

- in /usr/src/old/dump/dumpmain.c line 38-42(2)

max defined in line 336; never used
min defined in line 340; never used
msg defined in line 252; used 58 times

- in line 26, 47, 69, 80, 103, 143, 161, 230
- in /usr/src/old/dump/dumpitime.c line 62, 117, 124, 150-154(2), 172
- in /usr/src/old/dump/dumpmain.c line 139-141(3), 148, 156-160(2), 184, 190-193(2), 199-200(2), 209-219(8)
- in /usr/src/old/dump/dumptape.c line 60-65(4), 95, 101, 114, 160, 172, 178, 184, 191-200(4), 212, 219, 237, 247, 253, 260
- in /usr/src/old/dump/dumptraverse.c line 250-260(4)

msgtail defined in line 266; used 3 times

- in line 68
- in /usr/src/old/dump/dumpmain.c line 143-144(2)

query defined in line 18; used 6 times

- in line 81
- in /usr/src/old/dump/dumptape.c line 62, 118-120(2), 225
- in /usr/src/old/dump/dumptraverse.c line 261

sendmes defined in line 172; used 1 times

- in line 164

set_operators defined in line 96; used 1 times

- in /usr/src/old/dump/dumpmain.c line 124

timeest defined in line 206; used 1 times

- in /usr/src/old/dump/dumptape.c line 88

#### Defined variables

attnmessage defined in line 17; used 2 times

- in line 29, 70

gp defined in line 91; used 4 times

- in line 100-102(2), 137, 152

localclock defined in line 111; used 3 times

- in line 140, 188-189(2)

sccsid defined in line 1; never used
timeout defined in line 16; used 3 times

- in line 30, 67, 73

tschedule defined in line 204; used 2 times

- in line 213-214(2)

Last modified: 1996-11-18 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2005 |