1*6612Srrh static char *sccsid = "@(#)touch.c 1.4 (Berkeley) 05/04/82"; 21460Sroot #include <stdio.h> 31460Sroot #include <ctype.h> 41460Sroot #include <sys/types.h> 51460Sroot #include <sys/stat.h> 61460Sroot #include <signal.h> 71460Sroot #include "error.h" 81460Sroot 95595Srrh /* 105595Srrh * Iterate through errors 115595Srrh */ 125595Srrh #define EITERATE(p, fv, i) for (p = fv[i]; p < fv[i+1]; p++) 135595Srrh #define ECITERATE(ei, p, lb) for (ei = lb; p = errors[ei],ei < nerrors; ei++) 145595Srrh 155595Srrh #define FILEITERATE(fi, lb) for (fi = lb; fi <= nfiles; fi++) 165595Srrh int touchstatus = Q_YES; 175595Srrh 181460Sroot findfiles(nerrors, errors, r_nfiles, r_files) 195595Srrh int nerrors; 205595Srrh Eptr *errors; 215595Srrh int *r_nfiles; 225595Srrh Eptr ***r_files; 231460Sroot { 245595Srrh int nfiles; 255595Srrh Eptr **files; 261460Sroot 275595Srrh char *name; 285595Srrh reg int ei; 295595Srrh int fi; 305595Srrh reg Eptr errorp; 315595Srrh 325595Srrh nfiles = countfiles(errors); 335595Srrh 345595Srrh files = (Eptr**)Calloc(nfiles + 3, sizeof (Eptr*)); 351460Sroot touchedfiles = (boolean *)Calloc(nfiles+3, sizeof(boolean)); 361460Sroot /* 375595Srrh * Now, partition off the error messages 381460Sroot * into those that are synchronization, discarded or 391460Sroot * not specific to any file, and those that were 401460Sroot * nulled or true errors. 411460Sroot */ 421460Sroot files[0] = &errors[0]; 435595Srrh ECITERATE(ei, errorp, 0){ 445595Srrh if ( ! (NOTSORTABLE(errorp->error_e_class))) 455595Srrh break; 461460Sroot } 471460Sroot /* 485595Srrh * Now, and partition off all error messages 491460Sroot * for a given file. 501460Sroot */ 515595Srrh files[1] = &errors[ei]; 521460Sroot touchedfiles[0] = touchedfiles[1] = FALSE; 535595Srrh name = "\1"; 545595Srrh fi = 1; 555595Srrh ECITERATE(ei, errorp, ei){ 565595Srrh if ( (errorp->error_e_class == C_NULLED) 575595Srrh || (errorp->error_e_class == C_TRUE) ){ 585595Srrh if (strcmp(errorp->error_text[0], name) != 0){ 595595Srrh name = errorp->error_text[0]; 605595Srrh touchedfiles[fi] = FALSE; 615595Srrh files[fi] = &errors[ei]; 625595Srrh fi++; 631460Sroot } 641460Sroot } 651460Sroot } 665595Srrh files[fi] = &errors[nerrors]; 671460Sroot *r_nfiles = nfiles; 681460Sroot *r_files = files; 691460Sroot } 701460Sroot 715595Srrh int countfiles(errors) 725595Srrh Eptr *errors; 735595Srrh { 745595Srrh char *name; 755595Srrh int ei; 765595Srrh reg Eptr errorp; 775595Srrh 785595Srrh int nfiles; 795595Srrh nfiles = 0; 805595Srrh name = "\1"; 815595Srrh ECITERATE(ei, errorp, 0){ 825595Srrh if (SORTABLE(errorp->error_e_class)){ 835595Srrh if (strcmp(errorp->error_text[0],name) != 0){ 845595Srrh nfiles++; 855595Srrh name = errorp->error_text[0]; 865595Srrh } 875595Srrh } 885595Srrh } 895595Srrh return(nfiles); 905595Srrh } 911460Sroot char *class_table[] = { 921460Sroot /*C_UNKNOWN 0 */ "Unknown", 931460Sroot /*C_IGNORE 1 */ "ignore", 941460Sroot /*C_SYNC 2 */ "synchronization", 951460Sroot /*C_DISCARD 3 */ "discarded", 961460Sroot /*C_NONSPEC 4 */ "non specific", 971460Sroot /*C_THISFILE 5 */ "specific to this file", 981460Sroot /*C_NULLED 6 */ "nulled", 991460Sroot /*C_TRUE 7 */ "true", 1001460Sroot /*C_DUPL 8 */ "duplicated" 1011460Sroot }; 1021460Sroot 1031460Sroot int class_count[C_LAST - C_FIRST] = {0}; 1041460Sroot 1051460Sroot filenames(nfiles, files) 1061460Sroot int nfiles; 1075595Srrh Eptr **files; 1081460Sroot { 1095595Srrh reg int fi; 1105595Srrh char *sep = " "; 1115595Srrh extern char *class_table[]; 1125595Srrh int someerrors; 1131460Sroot 1141460Sroot /* 1155595Srrh * first, simply dump out errors that 1161460Sroot * don't pertain to any file 1171460Sroot */ 1185595Srrh someerrors = nopertain(files); 1195595Srrh 1201460Sroot if (nfiles){ 1211460Sroot someerrors++; 1225595Srrh fprintf(stdout, terse 1235595Srrh ? "%d file%s" 1245595Srrh : "%d file%s contain%s errors", 1255595Srrh nfiles, plural(nfiles), verbform(nfiles)); 1265595Srrh if (!terse){ 1275595Srrh FILEITERATE(fi, 1){ 1285595Srrh fprintf(stdout, "%s\"%s\" (%d)", 1295595Srrh sep, (*files[fi])->error_text[0], 1305595Srrh files[fi+1] - files[fi]); 1315595Srrh sep = ", "; 1325595Srrh } 1331460Sroot } 1341460Sroot fprintf(stdout, "\n"); 1351460Sroot } 1361460Sroot if (!someerrors) 1371460Sroot fprintf(stdout, "No errors.\n"); 1381460Sroot } 1391460Sroot 1405595Srrh /* 1415595Srrh * Dump out errors that don't pertain to any file 1425595Srrh */ 1435595Srrh int nopertain(files) 1445595Srrh Eptr **files; 1455595Srrh { 1465595Srrh int type; 1475595Srrh int someerrors = 0; 1485595Srrh reg Eptr *erpp; 1495595Srrh reg Eptr errorp; 1505595Srrh 1515595Srrh if (files[1] - files[0] <= 0) 1525595Srrh return(0); 1535595Srrh for(type = C_UNKNOWN; NOTSORTABLE(type); type++){ 1545595Srrh if (class_count[type] <= 0) 1555595Srrh continue; 1565595Srrh if (type > C_SYNC) 1575595Srrh someerrors++; 1585595Srrh if (terse){ 1595595Srrh fprintf(stdout, "\t%d %s errors NOT PRINTED\n", 1605595Srrh class_count[type], class_table[type]); 1615595Srrh } else { 1625595Srrh fprintf(stdout, "\n\t%d %s errors follow\n", 1635595Srrh class_count[type], class_table[type]); 1645595Srrh EITERATE(erpp, files, 0){ 1655595Srrh errorp = *erpp; 1665595Srrh if (errorp->error_e_class == type){ 1675595Srrh errorprint(stdout, errorp, TRUE); 1685595Srrh } 1695595Srrh } 1705595Srrh } 1715595Srrh } 1725595Srrh return(someerrors); 1735595Srrh } 1745595Srrh 1751460Sroot extern boolean notouch; 1761460Sroot 1771460Sroot boolean touchfiles(nfiles, files, r_edargc, r_edargv) 1781460Sroot int nfiles; 1795595Srrh Eptr **files; 1801460Sroot int *r_edargc; 1811460Sroot char ***r_edargv; 1821460Sroot { 1835595Srrh char *name; 1845595Srrh reg Eptr errorp; 1855595Srrh reg int fi; 1865595Srrh reg Eptr *erpp; 1875595Srrh int ntrueerrors; 1885595Srrh boolean scribbled; 1895595Srrh int n_pissed_on; /* # of file touched*/ 1905595Srrh int spread; 1911462Sroot 1925595Srrh FILEITERATE(fi, 1){ 1935595Srrh name = (*files[fi])->error_text[0]; 1945595Srrh spread = files[fi+1] - files[fi]; 1955595Srrh fprintf(stdout, terse 1965595Srrh ? "\"%s\" has %d error%s, " 1975595Srrh : "\nFile \"%s\" has %d error%s.\n" 1985595Srrh , name ,spread ,plural(spread)); 1991460Sroot /* 2001460Sroot * First, iterate through all error messages in this file 2011460Sroot * to see how many of the error messages really will 2021460Sroot * get inserted into the file. 2031460Sroot */ 2045595Srrh ntrueerrors = 0; 2055595Srrh EITERATE(erpp, files, fi){ 2061460Sroot errorp = *erpp; 2071460Sroot if (errorp->error_e_class == C_TRUE) 2081460Sroot ntrueerrors++; 2091460Sroot } 2105595Srrh fprintf(stdout, terse 2115595Srrh ? "insert %d\n" 2125595Srrh : "\t%d of these errors can be inserted into the file.\n", 2131460Sroot ntrueerrors); 2141460Sroot 2155595Srrh hackfile(name, files, fi, ntrueerrors); 2165595Srrh } 2171460Sroot scribbled = FALSE; 2185595Srrh n_pissed_on = 0; 2195595Srrh FILEITERATE(fi, 1){ 2205595Srrh scribbled |= touchedfiles[fi]; 2211460Sroot n_pissed_on++; 2221460Sroot } 2231460Sroot if (scribbled){ 2241460Sroot /* 2251460Sroot * Construct an execv argument 2261460Sroot */ 2275595Srrh execvarg(n_pissed_on, r_edargc, r_edargv); 2281460Sroot return(TRUE); 2291460Sroot } else { 2305595Srrh if (!terse) 2315595Srrh fprintf(stdout, "You didn't touch any files.\n"); 2321460Sroot return(FALSE); 2331460Sroot } 2345595Srrh } 2351460Sroot 2365595Srrh hackfile(name, files, ix, nerrors) 2375595Srrh char *name; 2385595Srrh Eptr **files; 2395595Srrh int ix; 2405595Srrh { 2415595Srrh boolean previewed; 2425595Srrh int errordest; /* where errors go*/ 2435595Srrh 2445595Srrh previewed = preview(name, nerrors, files, ix); 2455595Srrh 2465595Srrh errordest = settotouch(name); 2475595Srrh 2485595Srrh if (errordest != TOSTDOUT) 2495595Srrh touchedfiles[ix] = TRUE; 2505595Srrh 2515595Srrh if (previewed && (errordest == TOSTDOUT)) 2525595Srrh return; 2535595Srrh 2545595Srrh diverterrors(name, errordest, files, ix, previewed, nerrors); 2555595Srrh 256*6612Srrh if (errordest == TOTHEFILE){ 257*6612Srrh /* 258*6612Srrh * overwrite the original file 259*6612Srrh */ 260*6612Srrh writetouched(1); 261*6612Srrh } 2625595Srrh } 2635595Srrh 2645595Srrh boolean preview(name, nerrors, files, ix) 2655595Srrh char *name; 2665595Srrh int nerrors; 2675595Srrh Eptr **files; 2685595Srrh int ix; 2695595Srrh { 2705595Srrh int back; 2715595Srrh reg Eptr *erpp; 2725595Srrh 2735595Srrh if (!oktotouch(name)) 2745595Srrh return(false); 2755595Srrh if (nerrors <= 0) 2765595Srrh return(false); 2775595Srrh back = false; 2785595Srrh if(query){ 2795595Srrh switch(inquire(terse 2805595Srrh ? "Preview? " 2815595Srrh : "Do you want to preview the errors first? ")){ 2825595Srrh case Q_YES: 2835595Srrh case Q_yes: 2845595Srrh back = true; 2855595Srrh EITERATE(erpp, files, ix){ 2865595Srrh errorprint(stdout, *erpp, TRUE); 2875595Srrh } 2885595Srrh if (!terse) 2895595Srrh fprintf(stdout, "\n"); 2905595Srrh default: 2915595Srrh break; 2925595Srrh } 2935595Srrh } 2945595Srrh return(back); 2955595Srrh } 2965595Srrh 2975595Srrh int settotouch(name) 2985595Srrh char *name; 2995595Srrh { 3005595Srrh int dest = TOSTDOUT; 3015595Srrh 3025595Srrh if (query){ 3035595Srrh switch(touchstatus = inquire(terse 3045595Srrh ? "Touch? " 3055595Srrh : "Do you want to touch file \"%s\"? ", 3065595Srrh name)){ 3075595Srrh case Q_NO: 3085595Srrh case Q_no: 3095595Srrh return(dest); 3105595Srrh default: 3115595Srrh break; 3125595Srrh } 3135595Srrh } 3145595Srrh 3155595Srrh switch(probethisfile(name)){ 3165595Srrh case F_NOTREAD: 3175595Srrh dest = TOSTDOUT; 3185595Srrh fprintf(stdout, terse 3195595Srrh ? "\"%s\" unreadable\n" 3205595Srrh : "File \"%s\" is unreadable\n", 3215595Srrh name); 3225595Srrh break; 3235595Srrh case F_NOTWRITE: 3245595Srrh dest = TOSTDOUT; 3255595Srrh fprintf(stdout, terse 3265595Srrh ? "\"%s\" unwritable\n" 3275595Srrh : "File \"%s\" is unwritable\n", 3285595Srrh name); 3295595Srrh break; 3305595Srrh case F_NOTEXIST: 3315595Srrh dest = TOSTDOUT; 3325595Srrh fprintf(stdout, terse 3335595Srrh ? "\"%s\" not found\n" 3345595Srrh : "Can't find file \"%s\" to insert error messages into.\n", 3355595Srrh name); 3365595Srrh break; 3375595Srrh default: 3385595Srrh dest = edit(name) ? TOSTDOUT : TOTHEFILE; 3395595Srrh break; 3405595Srrh } 3415595Srrh return(dest); 3425595Srrh } 3435595Srrh 3445595Srrh diverterrors(name, dest, files, ix, previewed, nterrors) 3455595Srrh char *name; 3465595Srrh int dest; 3475595Srrh Eptr **files; 3485595Srrh int ix; 3495595Srrh boolean previewed; 3505595Srrh int nterrors; 3515595Srrh { 3525595Srrh int nerrors; 3535595Srrh reg Eptr *erpp; 3545595Srrh reg Eptr errorp; 3555595Srrh 3565595Srrh nerrors = files[ix+1] - files[ix]; 3575595Srrh 3585595Srrh if ( (nerrors != nterrors) 3595595Srrh && (!previewed) ){ 3605595Srrh fprintf(stdout, terse 3615595Srrh ? "Uninserted errors\n" 3625595Srrh : ">>Uninserted errors for file \"%s\" follow.\n", 3635595Srrh name); 3645595Srrh } 3655595Srrh 3665595Srrh EITERATE(erpp, files, ix){ 3675595Srrh errorp = *erpp; 3685595Srrh if (errorp->error_e_class != C_TRUE){ 3695595Srrh if (previewed || touchstatus == Q_NO) 3705595Srrh continue; 3715595Srrh errorprint(stdout, errorp, TRUE); 3725595Srrh continue; 3735595Srrh } 3745595Srrh switch (dest){ 3755595Srrh case TOSTDOUT: 3765595Srrh if (previewed || touchstatus == Q_NO) 3775595Srrh continue; 3785595Srrh errorprint(stdout,errorp, TRUE); 3795595Srrh break; 3805595Srrh case TOTHEFILE: 3815595Srrh insert(errorp->error_line); 3825595Srrh text(errorp, FALSE); 3835595Srrh break; 3845595Srrh } 3855595Srrh } 3865595Srrh } 3875595Srrh 3885595Srrh int oktotouch(filename) 3891460Sroot char *filename; 3901460Sroot { 3911460Sroot extern char *suffixlist; 3925595Srrh reg char *src; 3935595Srrh reg char *pat; 3941460Sroot char *osrc; 3951460Sroot 3961460Sroot pat = suffixlist; 3971460Sroot if (pat == 0) 3981460Sroot return(0); 3991460Sroot if (*pat == '*') 4001460Sroot return(1); 4011460Sroot while (*pat++ != '.') 4021460Sroot continue; 4031460Sroot --pat; /* point to the period */ 4041460Sroot 4051460Sroot for (src = &filename[strlen(filename)], --src; 4061460Sroot (src > filename) && (*src != '.'); --src) 4071460Sroot continue; 4081460Sroot if (*src != '.') 4091460Sroot return(0); 4101460Sroot 4111460Sroot for (src++, pat++, osrc = src; *src && *pat; src = osrc, pat++){ 4121460Sroot for (; *src /* not at end of the source */ 4131460Sroot && *pat /* not off end of pattern */ 4141460Sroot && *pat != '.' /* not off end of sub pattern */ 4151460Sroot && *pat != '*' /* not wild card */ 4161460Sroot && *src == *pat; /* and equal... */ 4171460Sroot src++, pat++) 4181460Sroot continue; 4191460Sroot if (*src == 0 && (*pat == 0 || *pat == '.' || *pat == '*')) 4201460Sroot return(1); 4211460Sroot if (*src != 0 && *pat == '*') 4221460Sroot return(1); 4231460Sroot while (*pat && *pat != '.') 4241460Sroot pat++; 4251460Sroot if (! *pat) 4261460Sroot return(0); 4271460Sroot } 4281460Sroot return(0); 4291460Sroot } 4305595Srrh /* 4315595Srrh * Construct an execv argument 4325595Srrh * We need 1 argument for the editor's name 4335595Srrh * We need 1 argument for the initial search string 4345595Srrh * We need n_pissed_on arguments for the file names 4355595Srrh * We need 1 argument that is a null for execv. 4365595Srrh * The caller fills in the editor's name. 4375595Srrh * We fill in the initial search string. 4385595Srrh * We fill in the arguments, and the null. 4395595Srrh */ 4405595Srrh execvarg(n_pissed_on, r_argc, r_argv) 4415595Srrh int n_pissed_on; 4425595Srrh int *r_argc; 4435595Srrh char ***r_argv; 4445595Srrh { 4455595Srrh Eptr p; 4465595Srrh char *sep; 4475595Srrh int fi; 4481460Sroot 4495595Srrh (*r_argv) = (char **)Calloc(n_pissed_on + 3, sizeof(char *)); 4505595Srrh (*r_argc) = n_pissed_on + 2; 4515595Srrh (*r_argv)[1] = "+1;/###/"; 4525595Srrh n_pissed_on = 2; 4535595Srrh if (!terse){ 4545595Srrh fprintf(stdout, "You touched file(s):"); 4555595Srrh sep = " "; 4565595Srrh } 4575595Srrh FILEITERATE(fi, 1){ 4585595Srrh if (!touchedfiles[fi]) 4595595Srrh continue; 4605595Srrh p = *(files[fi]); 4615595Srrh if (!terse){ 4625595Srrh fprintf(stdout,"%s\"%s\"", sep, p->error_text[0]); 4635595Srrh sep = ", "; 4645595Srrh } 4655595Srrh (*r_argv)[n_pissed_on++] = p->error_text[0]; 4665595Srrh } 4675595Srrh if (!terse) 4685595Srrh fprintf(stdout, "\n"); 4695595Srrh (*r_argv)[n_pissed_on] = 0; 4705595Srrh } 4715595Srrh 4721460Sroot FILE *o_touchedfile; /* the old file */ 4731460Sroot FILE *n_touchedfile; /* the new file */ 4741460Sroot char *o_name; 475*6612Srrh char n_name[64]; 476*6612Srrh char *canon_name = "/tmp/ErrorXXXXXX"; 4771460Sroot int o_lineno; 4781460Sroot int n_lineno; 4791460Sroot boolean tempfileopen = FALSE; 4801460Sroot /* 4811460Sroot * open the file; guaranteed to be both readable and writable 4821460Sroot * Well, if it isn't, then return TRUE if something failed 4831460Sroot */ 4841460Sroot boolean edit(name) 4851460Sroot char *name; 4861460Sroot { 4871460Sroot o_name = name; 4881460Sroot if ( (o_touchedfile = fopen(name, "r")) == NULL){ 4891460Sroot fprintf(stderr, "%s: Can't open file \"%s\" to touch (read).\n", 4901460Sroot processname, name); 4911460Sroot return(TRUE); 4921460Sroot } 4935595Srrh (void)strcpy(n_name, canon_name); 4945595Srrh (void)mktemp(n_name); 4951460Sroot if ( (n_touchedfile = fopen(n_name, "w")) == NULL){ 4961460Sroot fprintf(stderr,"%s: Can't open file \"%s\" to touch (write).\n", 4971460Sroot processname, name); 4981460Sroot return(TRUE); 4991460Sroot } 5001460Sroot tempfileopen = TRUE; 5011460Sroot n_lineno = 0; 5021460Sroot o_lineno = 0; 5031460Sroot return(FALSE); 5041460Sroot } 5051460Sroot /* 5061460Sroot * Position to the line (before, after) the line given by place 5071460Sroot */ 5085595Srrh char edbuf[BUFSIZ]; 5091460Sroot insert(place) 5101460Sroot int place; 5111460Sroot { 5121460Sroot --place; /* always insert messages before the offending line*/ 5131460Sroot for(; o_lineno < place; o_lineno++, n_lineno++){ 5145595Srrh if(fgets(edbuf, BUFSIZ, o_touchedfile) == NULL) 5151460Sroot return; 5165595Srrh fputs(edbuf, n_touchedfile); 5171460Sroot } 5181460Sroot } 5191460Sroot 5205595Srrh text(p, use_all) 5215595Srrh reg Eptr p; 5225595Srrh boolean use_all; 5231460Sroot { 5241460Sroot int offset = use_all ? 0 : 2; 5255595Srrh 5265595Srrh fputs(lang_table[p->error_language].lang_incomment, n_touchedfile); 5271460Sroot fprintf(n_touchedfile, "%d [%s] ", 5285595Srrh p->error_line, 5295595Srrh lang_table[p->error_language].lang_name); 5305595Srrh wordvprint(n_touchedfile, p->error_lgtext-offset, p->error_text+offset); 5315595Srrh fputs(lang_table[p->error_language].lang_outcomment,n_touchedfile); 5321460Sroot n_lineno++; 5331460Sroot } 5341460Sroot 535*6612Srrh /* 536*6612Srrh * write the touched file to its temporary copy, 537*6612Srrh * then bring the temporary in over the local file 538*6612Srrh */ 539*6612Srrh writetouched(overwrite) 540*6612Srrh int overwrite; 5411460Sroot { 542*6612Srrh reg int nread; 543*6612Srrh reg FILE *localfile; 544*6612Srrh reg FILE *tmpfile; 545*6612Srrh int botch; 5465595Srrh 5475595Srrh while((nread = fread(edbuf, 1, sizeof(edbuf), o_touchedfile)) != NULL){ 5485595Srrh fwrite(edbuf, 1, nread, n_touchedfile); 5491460Sroot } 5501460Sroot fclose(n_touchedfile); 5511460Sroot fclose(o_touchedfile); 552*6612Srrh /* 553*6612Srrh * Now, copy the temp file back over the original 554*6612Srrh * file, thus preserving links, etc 555*6612Srrh */ 556*6612Srrh if (overwrite){ 557*6612Srrh botch = 0; 558*6612Srrh localfile = NULL; 559*6612Srrh tmpfile = NULL; 560*6612Srrh if ((localfile = fopen(o_name, "w")) == NULL){ 561*6612Srrh fprintf(stderr, 562*6612Srrh "%s: Can't open file \"%s\" to overwrite.\n", 563*6612Srrh processname, o_name); 564*6612Srrh botch++; 565*6612Srrh } 566*6612Srrh if ((tmpfile = fopen(n_name, "r")) == NULL){ 567*6612Srrh fprintf(stderr, "%s: Can't open file \"%s\" to read.\n", 568*6612Srrh processname, n_name); 569*6612Srrh botch++; 570*6612Srrh } 571*6612Srrh if (!botch){ 572*6612Srrh while((nread=fread(edbuf, 1, sizeof(edbuf), tmpfile)) 573*6612Srrh != NULL){ 574*6612Srrh fwrite(edbuf, 1, nread, localfile); 575*6612Srrh } 576*6612Srrh } 577*6612Srrh if (localfile != NULL) 578*6612Srrh fclose(localfile); 579*6612Srrh if (tmpfile != NULL) 580*6612Srrh fclose(tmpfile); 581*6612Srrh } 582*6612Srrh /* 583*6612Srrh * Kiss the temp file good bye 584*6612Srrh */ 5851460Sroot unlink(n_name); 5861460Sroot tempfileopen = FALSE; 587*6612Srrh return(TRUE); 5881460Sroot } 5895595Srrh 5901460Sroot onintr() 5911460Sroot { 5925595Srrh switch(inquire(terse 5935595Srrh ? "\nContinue? " 5945595Srrh : "\nInterrupt: Do you want to continue? ")){ 5955595Srrh case Q_YES: 5965595Srrh case Q_yes: 5971460Sroot signal(SIGINT, onintr); 5981460Sroot return; 5995595Srrh default: 600*6612Srrh if (tempfileopen){ 601*6612Srrh /* 602*6612Srrh * Don't overwrite the original file! 603*6612Srrh */ 604*6612Srrh writetouched(0); 605*6612Srrh } 6065595Srrh exit(1); 6071460Sroot } 6085595Srrh /*NOTREACHED*/ 6091460Sroot } 6105595Srrh 6111460Sroot errorprint(place, errorp, print_all) 6121460Sroot FILE *place; 6135595Srrh Eptr errorp; 6141460Sroot boolean print_all; 6151460Sroot { 6161460Sroot int offset = print_all ? 0 : 2; 6171460Sroot 6181460Sroot if (errorp->error_e_class == C_IGNORE) 6191460Sroot return; 6201460Sroot fprintf(place, "[%s] ", lang_table[errorp->error_language].lang_name); 6211460Sroot wordvprint(place,errorp->error_lgtext-offset,errorp->error_text+offset); 6221460Sroot putc('\n', place); 6231460Sroot } 6241460Sroot 6255595Srrh int inquire(fmt, a1, a2) 6261460Sroot char *fmt; 6271460Sroot /*VARARGS1*/ 6281460Sroot { 6291460Sroot char buffer[128]; 6301460Sroot for(;;){ 6311460Sroot do{ 6321460Sroot fflush(stdout); 6331460Sroot fprintf(stderr, fmt, a1, a2); 6341460Sroot fflush(stderr); 6351460Sroot } while (fgets(buffer, 127, queryfile) == NULL); 6365595Srrh switch(buffer[0]){ 6375595Srrh case 'Y': return(Q_YES); 6385595Srrh case 'y': return(Q_yes); 6395595Srrh case 'N': return(Q_NO); 6405595Srrh case 'n': return(Q_no); 6415595Srrh default: fprintf(stderr, "Yes or No only!\n"); 6425595Srrh } 6431460Sroot } 6441460Sroot } 6451460Sroot 6465595Srrh int probethisfile(name) 6475595Srrh char *name; 6481460Sroot { 6491460Sroot struct stat statbuf; 6505595Srrh if (stat(name, &statbuf) < 0) 6515595Srrh return(F_NOTEXIST); 6525595Srrh if((statbuf.st_mode & S_IREAD) == 0) 6535595Srrh return(F_NOTREAD); 6545595Srrh if((statbuf.st_mode & S_IWRITE) == 0) 6555595Srrh return(F_NOTWRITE); 6565595Srrh return(F_TOUCHIT); 6571460Sroot } 658