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