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