1: /*
   2:  * Copyright (c) 1980 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[] = "@(#)errortouch.c	5.1 (Berkeley) 5/31/85";
   9: #endif not lint
  10: 
  11: #include <stdio.h>
  12: #include <ctype.h>
  13: #include <sys/types.h>
  14: #include <sys/stat.h>
  15: #include <signal.h>
  16: #include "error.h"
  17: 
  18: /*
  19:  *	Iterate through errors
  20:  */
  21: #define EITERATE(p, fv, i)  for (p = fv[i]; p < fv[i+1]; p++)
  22: #define ECITERATE(ei, p, lb)    for (ei = lb; p = errors[ei],ei < nerrors; ei++)
  23: 
  24: #define FILEITERATE(fi, lb) for (fi = lb; fi <= nfiles; fi++)
  25: int touchstatus = Q_YES;
  26: 
  27: findfiles(nerrors, errors, r_nfiles, r_files)
  28:         int nerrors;
  29:     Eptr    *errors;
  30:         int *r_nfiles;
  31:     Eptr    ***r_files;
  32: {
  33:         int nfiles;
  34:     Eptr    **files;
  35: 
  36:         char    *name;
  37:     reg int ei;
  38:         int fi;
  39:     reg Eptr    errorp;
  40: 
  41:     nfiles = countfiles(errors);
  42: 
  43:     files = (Eptr**)Calloc(nfiles + 3, sizeof (Eptr*));
  44:     touchedfiles = (boolean *)Calloc(nfiles+3, sizeof(boolean));
  45:     /*
  46: 	 *	Now, partition off the error messages
  47: 	 *	into those that are synchronization, discarded or
  48: 	 *	not specific to any file, and those that were
  49: 	 *	nulled or true errors.
  50: 	 */
  51:     files[0] = &errors[0];
  52:     ECITERATE(ei, errorp, 0){
  53:         if ( ! (NOTSORTABLE(errorp->error_e_class)))
  54:             break;
  55:     }
  56:     /*
  57: 	 *	Now, and partition off all error messages
  58: 	 *	for a given file.
  59: 	 */
  60:     files[1] = &errors[ei];
  61:     touchedfiles[0] = touchedfiles[1] = FALSE;
  62:     name = "\1";
  63:     fi = 1;
  64:     ECITERATE(ei, errorp, ei){
  65:         if (   (errorp->error_e_class == C_NULLED)
  66:             || (errorp->error_e_class == C_TRUE) ){
  67:             if (strcmp(errorp->error_text[0], name) != 0){
  68:                 name = errorp->error_text[0];
  69:                 touchedfiles[fi] = FALSE;
  70:                 files[fi] = &errors[ei];
  71:                 fi++;
  72:             }
  73:         }
  74:     }
  75:     files[fi] = &errors[nerrors];
  76:     *r_nfiles = nfiles;
  77:     *r_files = files;
  78: }
  79: 
  80: int countfiles(errors)
  81:     Eptr    *errors;
  82: {
  83:     char    *name;
  84:     int ei;
  85:     reg Eptr    errorp;
  86: 
  87:     int nfiles;
  88:     nfiles = 0;
  89:     name = "\1";
  90:     ECITERATE(ei, errorp, 0){
  91:         if (SORTABLE(errorp->error_e_class)){
  92:             if (strcmp(errorp->error_text[0],name) != 0){
  93:                 nfiles++;
  94:                 name = errorp->error_text[0];
  95:             }
  96:         }
  97:     }
  98:     return(nfiles);
  99: }
 100: char    *class_table[] = {
 101:     /*C_UNKNOWN	0	*/    "Unknown",
 102:     /*C_IGNORE	1	*/ "ignore",
 103:     /*C_SYNC	2	*/   "synchronization",
 104:     /*C_DISCARD	3	*/    "discarded",
 105:     /*C_NONSPEC	4	*/    "non specific",
 106:     /*C_THISFILE	5	*/   "specific to this file",
 107:     /*C_NULLED	6	*/ "nulled",
 108:     /*C_TRUE	7	*/   "true",
 109:     /*C_DUPL	8	*/   "duplicated"
 110: };
 111: 
 112: int class_count[C_LAST - C_FIRST] = {0};
 113: 
 114: filenames(nfiles, files)
 115:     int nfiles;
 116:     Eptr    **files;
 117: {
 118:     reg int fi;
 119:         char    *sep = " ";
 120:     extern  char    *class_table[];
 121:         int someerrors;
 122: 
 123:     /*
 124: 	 *	first, simply dump out errors that
 125: 	 *	don't pertain to any file
 126: 	 */
 127:     someerrors = nopertain(files);
 128: 
 129:     if (nfiles){
 130:         someerrors++;
 131:         fprintf(stdout, terse
 132:             ? "%d file%s"
 133:             : "%d file%s contain%s errors",
 134:             nfiles, plural(nfiles), verbform(nfiles));
 135:         if (!terse){
 136:             FILEITERATE(fi, 1){
 137:                 fprintf(stdout, "%s\"%s\" (%d)",
 138:                     sep, (*files[fi])->error_text[0],
 139:                     files[fi+1] - files[fi]);
 140:                 sep = ", ";
 141:             }
 142:         }
 143:         fprintf(stdout, "\n");
 144:     }
 145:     if (!someerrors)
 146:         fprintf(stdout, "No errors.\n");
 147: }
 148: 
 149: /*
 150:  *	Dump out errors that don't pertain to any file
 151:  */
 152: int nopertain(files)
 153:     Eptr    **files;
 154: {
 155:     int type;
 156:     int someerrors = 0;
 157:     reg Eptr    *erpp;
 158:     reg Eptr    errorp;
 159: 
 160:     if (files[1] - files[0] <= 0)
 161:         return(0);
 162:     for(type = C_UNKNOWN; NOTSORTABLE(type); type++){
 163:         if (class_count[type] <= 0)
 164:             continue;
 165:         if (type > C_SYNC)
 166:             someerrors++;
 167:         if (terse){
 168:             fprintf(stdout, "\t%d %s errors NOT PRINTED\n",
 169:                 class_count[type], class_table[type]);
 170:         } else {
 171:             fprintf(stdout, "\n\t%d %s errors follow\n",
 172:                 class_count[type], class_table[type]);
 173:             EITERATE(erpp, files, 0){
 174:                 errorp = *erpp;
 175:                 if (errorp->error_e_class == type){
 176:                     errorprint(stdout, errorp, TRUE);
 177:                 }
 178:             }
 179:         }
 180:     }
 181:     return(someerrors);
 182: }
 183: 
 184: extern  boolean notouch;
 185: 
 186: boolean touchfiles(nfiles, files, r_edargc, r_edargv)
 187:     int nfiles;
 188:     Eptr    **files;
 189:     int *r_edargc;
 190:     char    ***r_edargv;
 191: {
 192:         char    *name;
 193:     reg Eptr    errorp;
 194:     reg int fi;
 195:     reg Eptr    *erpp;
 196:         int     ntrueerrors;
 197:         boolean     scribbled;
 198:         int     n_pissed_on;    /* # of file touched*/
 199:         int spread;
 200: 
 201:     FILEITERATE(fi, 1){
 202:         name = (*files[fi])->error_text[0];
 203:         spread = files[fi+1] - files[fi];
 204:         fprintf(stdout, terse
 205:             ? "\"%s\" has %d error%s, "
 206:             : "\nFile \"%s\" has %d error%s.\n"
 207:             , name ,spread ,plural(spread));
 208:         /*
 209: 		 *	First, iterate through all error messages in this file
 210: 		 *	to see how many of the error messages really will
 211: 		 *	get inserted into the file.
 212: 		 */
 213:         ntrueerrors = 0;
 214:         EITERATE(erpp, files, fi){
 215:             errorp = *erpp;
 216:             if (errorp->error_e_class == C_TRUE)
 217:                 ntrueerrors++;
 218:         }
 219:         fprintf(stdout, terse
 220:           ? "insert %d\n"
 221:           : "\t%d of these errors can be inserted into the file.\n",
 222:             ntrueerrors);
 223: 
 224:         hackfile(name, files, fi, ntrueerrors);
 225:     }
 226:     scribbled = FALSE;
 227:     n_pissed_on = 0;
 228:     FILEITERATE(fi, 1){
 229:         scribbled |= touchedfiles[fi];
 230:         n_pissed_on++;
 231:     }
 232:     if (scribbled){
 233:         /*
 234: 		 *	Construct an execv argument
 235: 		 */
 236:         execvarg(n_pissed_on, r_edargc, r_edargv);
 237:         return(TRUE);
 238:     } else {
 239:         if (!terse)
 240:             fprintf(stdout, "You didn't touch any files.\n");
 241:         return(FALSE);
 242:     }
 243: }
 244: 
 245: hackfile(name, files, ix, nerrors)
 246:     char    *name;
 247:     Eptr    **files;
 248:     int ix;
 249: {
 250:     boolean previewed;
 251:     int errordest;  /* where errors go*/
 252: 
 253:     if (!oktotouch(name)) {
 254:         previewed = FALSE;
 255:         errordest = TOSTDOUT;
 256:     } else {
 257:         previewed = preview(name, nerrors, files, ix);
 258:         errordest = settotouch(name);
 259:     }
 260: 
 261:     if (errordest != TOSTDOUT)
 262:         touchedfiles[ix] = TRUE;
 263: 
 264:     if (previewed && (errordest == TOSTDOUT))
 265:         return;
 266: 
 267:     diverterrors(name, errordest, files, ix, previewed, nerrors);
 268: 
 269:     if (errordest == TOTHEFILE){
 270:         /*
 271: 		 *	overwrite the original file
 272: 		 */
 273:         writetouched(1);
 274:     }
 275: }
 276: 
 277: boolean preview(name, nerrors, files, ix)
 278:     char    *name;
 279:     int nerrors;
 280:     Eptr    **files;
 281:     int ix;
 282: {
 283:     int back;
 284:     reg Eptr    *erpp;
 285: 
 286:     if (nerrors <= 0)
 287:         return(FALSE);
 288:     back = FALSE;
 289:     if(query){
 290:         switch(inquire(terse
 291:             ? "Preview? "
 292:             : "Do you want to preview the errors first? ")){
 293:         case Q_YES:
 294:         case Q_yes:
 295:             back = TRUE;
 296:             EITERATE(erpp, files, ix){
 297:                 errorprint(stdout, *erpp, TRUE);
 298:             }
 299:             if (!terse)
 300:                 fprintf(stdout, "\n");
 301:         default:
 302:             break;
 303:         }
 304:     }
 305:     return(back);
 306: }
 307: 
 308: int settotouch(name)
 309:     char    *name;
 310: {
 311:     int dest = TOSTDOUT;
 312: 
 313:     if (query){
 314:         switch(touchstatus = inquire(terse
 315:             ? "Touch? "
 316:             : "Do you want to touch file \"%s\"? ",
 317:             name)){
 318:         case Q_NO:
 319:         case Q_no:
 320:             return(dest);
 321:         default:
 322:             break;
 323:         }
 324:     }
 325: 
 326:     switch(probethisfile(name)){
 327:     case F_NOTREAD:
 328:         dest = TOSTDOUT;
 329:         fprintf(stdout, terse
 330:             ? "\"%s\" unreadable\n"
 331:             : "File \"%s\" is unreadable\n",
 332:             name);
 333:         break;
 334:     case F_NOTWRITE:
 335:         dest = TOSTDOUT;
 336:         fprintf(stdout, terse
 337:             ? "\"%s\" unwritable\n"
 338:             : "File \"%s\" is unwritable\n",
 339:             name);
 340:         break;
 341:     case F_NOTEXIST:
 342:         dest = TOSTDOUT;
 343:         fprintf(stdout, terse
 344:             ? "\"%s\" not found\n"
 345:             : "Can't find file \"%s\" to insert error messages into.\n",
 346:             name);
 347:         break;
 348:     default:
 349:         dest = edit(name) ? TOSTDOUT : TOTHEFILE;
 350:         break;
 351:     }
 352:     return(dest);
 353: }
 354: 
 355: diverterrors(name, dest, files, ix, previewed, nterrors)
 356:     char    *name;
 357:     int dest;
 358:     Eptr    **files;
 359:     int ix;
 360:     boolean previewed;
 361:     int nterrors;
 362: {
 363:     int nerrors;
 364:     reg Eptr    *erpp;
 365:     reg Eptr    errorp;
 366: 
 367:     nerrors = files[ix+1] - files[ix];
 368: 
 369:     if (   (nerrors != nterrors)
 370:         && (!previewed) ){
 371:         fprintf(stdout, terse
 372:             ? "Uninserted errors\n"
 373:             : ">>Uninserted errors for file \"%s\" follow.\n",
 374:             name);
 375:     }
 376: 
 377:     EITERATE(erpp, files, ix){
 378:         errorp = *erpp;
 379:         if (errorp->error_e_class != C_TRUE){
 380:             if (previewed || touchstatus == Q_NO)
 381:                 continue;
 382:             errorprint(stdout, errorp, TRUE);
 383:             continue;
 384:         }
 385:         switch (dest){
 386:         case TOSTDOUT:
 387:             if (previewed || touchstatus == Q_NO)
 388:                 continue;
 389:             errorprint(stdout,errorp, TRUE);
 390:             break;
 391:         case TOTHEFILE:
 392:             insert(errorp->error_line);
 393:             text(errorp, FALSE);
 394:             break;
 395:         }
 396:     }
 397: }
 398: 
 399: int oktotouch(filename)
 400:     char    *filename;
 401: {
 402:     extern      char    *suffixlist;
 403:     reg char    *src;
 404:     reg char    *pat;
 405:             char    *osrc;
 406: 
 407:     pat = suffixlist;
 408:     if (pat == 0)
 409:         return(0);
 410:     if (*pat == '*')
 411:         return(1);
 412:     while (*pat++ != '.')
 413:         continue;
 414:     --pat;      /* point to the period */
 415: 
 416:     for (src = &filename[strlen(filename)], --src;
 417:          (src > filename) && (*src != '.'); --src)
 418:         continue;
 419:     if (*src != '.')
 420:         return(0);
 421: 
 422:     for (src++, pat++, osrc = src; *src && *pat; src = osrc, pat++){
 423:         for (;   *src           /* not at end of the source */
 424:               && *pat           /* not off end of pattern */
 425:               && *pat != '.'        /* not off end of sub pattern */
 426:               && *pat != '*'        /* not wild card */
 427:               && *src == *pat;      /* and equal... */
 428:               src++, pat++)
 429:             continue;
 430:         if (*src == 0 && (*pat == 0 || *pat == '.' || *pat == '*'))
 431:             return(1);
 432:         if (*src != 0 && *pat == '*')
 433:             return(1);
 434:         while (*pat && *pat != '.')
 435:             pat++;
 436:         if (! *pat)
 437:             return(0);
 438:     }
 439:     return(0);
 440: }
 441: /*
 442:  *	Construct an execv argument
 443:  *	We need 1 argument for the editor's name
 444:  *	We need 1 argument for the initial search string
 445:  *	We need n_pissed_on arguments for the file names
 446:  *	We need 1 argument that is a null for execv.
 447:  *	The caller fills in the editor's name.
 448:  *	We fill in the initial search string.
 449:  *	We fill in the arguments, and the null.
 450:  */
 451: execvarg(n_pissed_on, r_argc, r_argv)
 452:     int n_pissed_on;
 453:     int *r_argc;
 454:     char    ***r_argv;
 455: {
 456:     Eptr    p;
 457:     char    *sep;
 458:     int fi;
 459: 
 460:     (*r_argv) = (char **)Calloc(n_pissed_on + 3, sizeof(char *));
 461:     (*r_argc) =  n_pissed_on + 2;
 462:     (*r_argv)[1] = "+1;/###/";
 463:     n_pissed_on = 2;
 464:     if (!terse){
 465:         fprintf(stdout, "You touched file(s):");
 466:         sep = " ";
 467:     }
 468:     FILEITERATE(fi, 1){
 469:         if (!touchedfiles[fi])
 470:             continue;
 471:         p = *(files[fi]);
 472:         if (!terse){
 473:             fprintf(stdout,"%s\"%s\"", sep, p->error_text[0]);
 474:             sep = ", ";
 475:         }
 476:         (*r_argv)[n_pissed_on++] = p->error_text[0];
 477:     }
 478:     if (!terse)
 479:         fprintf(stdout, "\n");
 480:     (*r_argv)[n_pissed_on] = 0;
 481: }
 482: 
 483: FILE    *o_touchedfile; /* the old file */
 484: FILE    *n_touchedfile; /* the new file */
 485: char    *o_name;
 486: char    n_name[64];
 487: char    *canon_name = "/tmp/ErrorXXXXXX";
 488: int o_lineno;
 489: int n_lineno;
 490: boolean tempfileopen = FALSE;
 491: /*
 492:  *	open the file; guaranteed to be both readable and writable
 493:  *	Well, if it isn't, then return TRUE if something failed
 494:  */
 495: boolean edit(name)
 496:     char    *name;
 497: {
 498:     o_name = name;
 499:     if ( (o_touchedfile = fopen(name, "r")) == NULL){
 500:         fprintf(stderr, "%s: Can't open file \"%s\" to touch (read).\n",
 501:             processname, name);
 502:         return(TRUE);
 503:     }
 504:     (void)strcpy(n_name, canon_name);
 505:     (void)mktemp(n_name);
 506:     if ( (n_touchedfile = fopen(n_name, "w")) == NULL){
 507:         fprintf(stderr,"%s: Can't open file \"%s\" to touch (write).\n",
 508:             processname, name);
 509:         return(TRUE);
 510:     }
 511:     tempfileopen = TRUE;
 512:     n_lineno = 0;
 513:     o_lineno = 0;
 514:     return(FALSE);
 515: }
 516: /*
 517:  *	Position to the line (before, after) the line given by place
 518:  */
 519: char    edbuf[BUFSIZ];
 520: insert(place)
 521:     int place;
 522: {
 523:     --place;    /* always insert messages before the offending line*/
 524:     for(; o_lineno < place; o_lineno++, n_lineno++){
 525:         if(fgets(edbuf, BUFSIZ, o_touchedfile) == NULL)
 526:             return;
 527:         fputs(edbuf, n_touchedfile);
 528:     }
 529: }
 530: 
 531: text(p, use_all)
 532:     reg Eptr    p;
 533:         boolean use_all;
 534: {
 535:     int offset = use_all ? 0 : 2;
 536: 
 537:     fputs(lang_table[p->error_language].lang_incomment, n_touchedfile);
 538:     fprintf(n_touchedfile, "%d [%s] ",
 539:         p->error_line,
 540:         lang_table[p->error_language].lang_name);
 541:     wordvprint(n_touchedfile, p->error_lgtext-offset, p->error_text+offset);
 542:     fputs(lang_table[p->error_language].lang_outcomment,n_touchedfile);
 543:     n_lineno++;
 544: }
 545: 
 546: /*
 547:  *	write the touched file to its temporary copy,
 548:  *	then bring the temporary in over the local file
 549:  */
 550: writetouched(overwrite)
 551:     int overwrite;
 552: {
 553:     reg int nread;
 554:     reg FILE    *localfile;
 555:     reg FILE    *tmpfile;
 556:         int botch;
 557:         int oktorm;
 558: 
 559:     botch = 0;
 560:     oktorm = 1;
 561:     while((nread = fread(edbuf, 1, sizeof(edbuf), o_touchedfile)) != NULL){
 562:         if (nread != fwrite(edbuf, 1, nread, n_touchedfile)){
 563:             /*
 564: 			 *	Catastrophe in temporary area: file system full?
 565: 			 */
 566:             botch = 1;
 567:             fprintf(stderr,
 568:               "%s: write failure: No errors inserted in \"%s\"\n",
 569:               processname, o_name);
 570:         }
 571:     }
 572:     fclose(n_touchedfile);
 573:     fclose(o_touchedfile);
 574:     /*
 575: 	 *	Now, copy the temp file back over the original
 576: 	 *	file, thus preserving links, etc
 577: 	 */
 578:     if (botch == 0 && overwrite){
 579:         botch = 0;
 580:         localfile = NULL;
 581:         tmpfile = NULL;
 582:         if ((localfile = fopen(o_name, "w")) == NULL){
 583:             fprintf(stderr,
 584:                 "%s: Can't open file \"%s\" to overwrite.\n",
 585:                 processname, o_name);
 586:             botch++;
 587:         }
 588:         if ((tmpfile = fopen(n_name, "r")) == NULL){
 589:             fprintf(stderr, "%s: Can't open file \"%s\" to read.\n",
 590:                 processname, n_name);
 591:             botch++;
 592:         }
 593:         if (!botch)
 594:             oktorm = mustoverwrite(localfile, tmpfile);
 595:         if (localfile != NULL)
 596:             fclose(localfile);
 597:         if (tmpfile != NULL)
 598:             fclose(tmpfile);
 599:     }
 600:     if (oktorm == 0){
 601:         fprintf(stderr, "%s: Catastrophe: A copy of \"%s\: was saved in \"%s\"\n",
 602:             processname, o_name, n_name);
 603:         exit(1);
 604:     }
 605:     /*
 606: 	 *	Kiss the temp file good bye
 607: 	 */
 608:     unlink(n_name);
 609:     tempfileopen = FALSE;
 610:     return(TRUE);
 611: }
 612: /*
 613:  *	return 1 if the tmpfile can be removed after writing it out
 614:  */
 615: int mustoverwrite(preciousfile, tmpfile)
 616:     FILE    *preciousfile;
 617:     FILE    *tmpfile;
 618: {
 619:     int nread;
 620: 
 621:     while((nread = fread(edbuf, 1, sizeof(edbuf), tmpfile)) != NULL){
 622:         if (mustwrite(edbuf, nread, preciousfile) == 0)
 623:             return(0);
 624:     }
 625:     return(1);
 626: }
 627: /*
 628:  *	return 0 on catastrophe
 629:  */
 630: mustwrite(base, n, preciousfile)
 631:     char    *base;
 632:     int n;
 633:     FILE    *preciousfile;
 634: {
 635:     int nwrote;
 636: 
 637:     if (n <= 0)
 638:         return(1);
 639:     nwrote = fwrite(base, 1, n, preciousfile);
 640:     if (nwrote == n)
 641:         return(1);
 642:     perror(processname);
 643:     switch(inquire(terse
 644:         ? "Botch overwriting: retry? "
 645:         : "Botch overwriting the source file: retry? ")){
 646:     case Q_YES:
 647:     case Q_yes:
 648:         mustwrite(base + nwrote, n - nwrote, preciousfile);
 649:         return(1);
 650:     case Q_NO:
 651:     case Q_no:
 652:         switch(inquire("Are you sure? ")){
 653:         case Q_YES:
 654:         case Q_yes:
 655:             return(0);
 656:         case Q_NO:
 657:         case Q_no:
 658:             mustwrite(base + nwrote, n - nwrote, preciousfile);
 659:             return(1);
 660:         }
 661:     default:
 662:         return(0);
 663:     }
 664: }
 665: 
 666: onintr()
 667: {
 668:     switch(inquire(terse
 669:         ? "\nContinue? "
 670:         : "\nInterrupt: Do you want to continue? ")){
 671:     case Q_YES:
 672:     case Q_yes:
 673:         signal(SIGINT, onintr);
 674:         return;
 675:     default:
 676:         if (tempfileopen){
 677:             /*
 678: 			 *	Don't overwrite the original file!
 679: 			 */
 680:             writetouched(0);
 681:         }
 682:         exit(1);
 683:     }
 684:     /*NOTREACHED*/
 685: }
 686: 
 687: errorprint(place, errorp, print_all)
 688:     FILE    *place;
 689:     Eptr    errorp;
 690:     boolean print_all;
 691: {
 692:     int offset = print_all ? 0 : 2;
 693: 
 694:     if (errorp->error_e_class == C_IGNORE)
 695:         return;
 696:     fprintf(place, "[%s] ", lang_table[errorp->error_language].lang_name);
 697:     wordvprint(place,errorp->error_lgtext-offset,errorp->error_text+offset);
 698:     putc('\n', place);
 699: }
 700: 
 701: int inquire(fmt, a1, a2)
 702:     char    *fmt;
 703:     /*VARARGS1*/
 704: {
 705:     char    buffer[128];
 706: 
 707:     if (queryfile == NULL)
 708:         return(0);
 709:     for(;;){
 710:         do{
 711:             fflush(stdout);
 712:             fprintf(stderr, fmt, a1, a2);
 713:             fflush(stderr);
 714:         } while (fgets(buffer, 127, queryfile) == NULL);
 715:         switch(buffer[0]){
 716:         case 'Y':   return(Q_YES);
 717:         case 'y':   return(Q_yes);
 718:         case 'N':   return(Q_NO);
 719:         case 'n':   return(Q_no);
 720:         default:    fprintf(stderr, "Yes or No only!\n");
 721:         }
 722:     }
 723: }
 724: 
 725: int probethisfile(name)
 726:     char    *name;
 727: {
 728:     struct stat statbuf;
 729:     if (stat(name, &statbuf) < 0)
 730:         return(F_NOTEXIST);
 731:     if((statbuf.st_mode & S_IREAD) == 0)
 732:         return(F_NOTREAD);
 733:     if((statbuf.st_mode & S_IWRITE) == 0)
 734:         return(F_NOTWRITE);
 735:     return(F_TOUCHIT);
 736: }

Defined functions

countfiles defined in line 80; used 1 times
  • in line 41
diverterrors defined in line 355; used 1 times
edit defined in line 495; used 1 times
errorprint defined in line 687; used 4 times
execvarg defined in line 451; used 1 times
filenames defined in line 114; used 1 times
findfiles defined in line 27; used 1 times
hackfile defined in line 245; used 1 times
inquire defined in line 701; used 7 times
insert defined in line 520; used 1 times
mustoverwrite defined in line 615; used 1 times
mustwrite defined in line 630; used 3 times
nopertain defined in line 152; used 1 times
oktotouch defined in line 399; used 1 times
onintr defined in line 666; used 4 times
preview defined in line 277; used 1 times
probethisfile defined in line 725; used 2 times
settotouch defined in line 308; used 1 times
text defined in line 531; used 1 times
touchfiles defined in line 186; used 1 times
writetouched defined in line 550; used 2 times

Defined variables

canon_name defined in line 487; used 1 times
class_count defined in line 112; used 15 times
class_table defined in line 100; used 7 times
edbuf defined in line 519; used 8 times
n_lineno defined in line 489; used 3 times
n_name defined in line 486; used 7 times
o_lineno defined in line 488; used 3 times
o_name defined in line 485; used 5 times
sccsid defined in line 8; never used
tempfileopen defined in line 490; used 3 times
touchstatus defined in line 25; used 3 times

Defined macros

ECITERATE defined in line 22; used 3 times
EITERATE defined in line 21; used 4 times
FILEITERATE defined in line 24; used 4 times
Last modified: 1987-02-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5037
Valid CSS Valid XHTML 1.0 Strict