1*5595Srrh static char *sccsid = "@(#)touch.c 1.3 (Berkeley) 01/22/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 9*5595Srrh /* 10*5595Srrh * Iterate through errors 11*5595Srrh */ 12*5595Srrh #define EITERATE(p, fv, i) for (p = fv[i]; p < fv[i+1]; p++) 13*5595Srrh #define ECITERATE(ei, p, lb) for (ei = lb; p = errors[ei],ei < nerrors; ei++) 14*5595Srrh 15*5595Srrh #define FILEITERATE(fi, lb) for (fi = lb; fi <= nfiles; fi++) 16*5595Srrh int touchstatus = Q_YES; 17*5595Srrh 181460Sroot findfiles(nerrors, errors, r_nfiles, r_files) 19*5595Srrh int nerrors; 20*5595Srrh Eptr *errors; 21*5595Srrh int *r_nfiles; 22*5595Srrh Eptr ***r_files; 231460Sroot { 24*5595Srrh int nfiles; 25*5595Srrh Eptr **files; 261460Sroot 27*5595Srrh char *name; 28*5595Srrh reg int ei; 29*5595Srrh int fi; 30*5595Srrh reg Eptr errorp; 31*5595Srrh 32*5595Srrh nfiles = countfiles(errors); 33*5595Srrh 34*5595Srrh files = (Eptr**)Calloc(nfiles + 3, sizeof (Eptr*)); 351460Sroot touchedfiles = (boolean *)Calloc(nfiles+3, sizeof(boolean)); 361460Sroot /* 37*5595Srrh * 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]; 43*5595Srrh ECITERATE(ei, errorp, 0){ 44*5595Srrh if ( ! (NOTSORTABLE(errorp->error_e_class))) 45*5595Srrh break; 461460Sroot } 471460Sroot /* 48*5595Srrh * Now, and partition off all error messages 491460Sroot * for a given file. 501460Sroot */ 51*5595Srrh files[1] = &errors[ei]; 521460Sroot touchedfiles[0] = touchedfiles[1] = FALSE; 53*5595Srrh name = "\1"; 54*5595Srrh fi = 1; 55*5595Srrh ECITERATE(ei, errorp, ei){ 56*5595Srrh if ( (errorp->error_e_class == C_NULLED) 57*5595Srrh || (errorp->error_e_class == C_TRUE) ){ 58*5595Srrh if (strcmp(errorp->error_text[0], name) != 0){ 59*5595Srrh name = errorp->error_text[0]; 60*5595Srrh touchedfiles[fi] = FALSE; 61*5595Srrh files[fi] = &errors[ei]; 62*5595Srrh fi++; 631460Sroot } 641460Sroot } 651460Sroot } 66*5595Srrh files[fi] = &errors[nerrors]; 671460Sroot *r_nfiles = nfiles; 681460Sroot *r_files = files; 691460Sroot } 701460Sroot 71*5595Srrh int countfiles(errors) 72*5595Srrh Eptr *errors; 73*5595Srrh { 74*5595Srrh char *name; 75*5595Srrh int ei; 76*5595Srrh reg Eptr errorp; 77*5595Srrh 78*5595Srrh int nfiles; 79*5595Srrh nfiles = 0; 80*5595Srrh name = "\1"; 81*5595Srrh ECITERATE(ei, errorp, 0){ 82*5595Srrh if (SORTABLE(errorp->error_e_class)){ 83*5595Srrh if (strcmp(errorp->error_text[0],name) != 0){ 84*5595Srrh nfiles++; 85*5595Srrh name = errorp->error_text[0]; 86*5595Srrh } 87*5595Srrh } 88*5595Srrh } 89*5595Srrh return(nfiles); 90*5595Srrh } 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; 107*5595Srrh Eptr **files; 1081460Sroot { 109*5595Srrh reg int fi; 110*5595Srrh char *sep = " "; 111*5595Srrh extern char *class_table[]; 112*5595Srrh int someerrors; 1131460Sroot 1141460Sroot /* 115*5595Srrh * first, simply dump out errors that 1161460Sroot * don't pertain to any file 1171460Sroot */ 118*5595Srrh someerrors = nopertain(files); 119*5595Srrh 1201460Sroot if (nfiles){ 1211460Sroot someerrors++; 122*5595Srrh fprintf(stdout, terse 123*5595Srrh ? "%d file%s" 124*5595Srrh : "%d file%s contain%s errors", 125*5595Srrh nfiles, plural(nfiles), verbform(nfiles)); 126*5595Srrh if (!terse){ 127*5595Srrh FILEITERATE(fi, 1){ 128*5595Srrh fprintf(stdout, "%s\"%s\" (%d)", 129*5595Srrh sep, (*files[fi])->error_text[0], 130*5595Srrh files[fi+1] - files[fi]); 131*5595Srrh sep = ", "; 132*5595Srrh } 1331460Sroot } 1341460Sroot fprintf(stdout, "\n"); 1351460Sroot } 1361460Sroot if (!someerrors) 1371460Sroot fprintf(stdout, "No errors.\n"); 1381460Sroot } 1391460Sroot 140*5595Srrh /* 141*5595Srrh * Dump out errors that don't pertain to any file 142*5595Srrh */ 143*5595Srrh int nopertain(files) 144*5595Srrh Eptr **files; 145*5595Srrh { 146*5595Srrh int type; 147*5595Srrh int someerrors = 0; 148*5595Srrh reg Eptr *erpp; 149*5595Srrh reg Eptr errorp; 150*5595Srrh 151*5595Srrh if (files[1] - files[0] <= 0) 152*5595Srrh return(0); 153*5595Srrh for(type = C_UNKNOWN; NOTSORTABLE(type); type++){ 154*5595Srrh if (class_count[type] <= 0) 155*5595Srrh continue; 156*5595Srrh if (type > C_SYNC) 157*5595Srrh someerrors++; 158*5595Srrh if (terse){ 159*5595Srrh fprintf(stdout, "\t%d %s errors NOT PRINTED\n", 160*5595Srrh class_count[type], class_table[type]); 161*5595Srrh } else { 162*5595Srrh fprintf(stdout, "\n\t%d %s errors follow\n", 163*5595Srrh class_count[type], class_table[type]); 164*5595Srrh EITERATE(erpp, files, 0){ 165*5595Srrh errorp = *erpp; 166*5595Srrh if (errorp->error_e_class == type){ 167*5595Srrh errorprint(stdout, errorp, TRUE); 168*5595Srrh } 169*5595Srrh } 170*5595Srrh } 171*5595Srrh } 172*5595Srrh return(someerrors); 173*5595Srrh } 174*5595Srrh 1751460Sroot extern boolean notouch; 1761460Sroot 1771460Sroot boolean touchfiles(nfiles, files, r_edargc, r_edargv) 1781460Sroot int nfiles; 179*5595Srrh Eptr **files; 1801460Sroot int *r_edargc; 1811460Sroot char ***r_edargv; 1821460Sroot { 183*5595Srrh char *name; 184*5595Srrh reg Eptr errorp; 185*5595Srrh reg int fi; 186*5595Srrh reg Eptr *erpp; 187*5595Srrh int ntrueerrors; 188*5595Srrh boolean scribbled; 189*5595Srrh int n_pissed_on; /* # of file touched*/ 190*5595Srrh int spread; 1911462Sroot 192*5595Srrh FILEITERATE(fi, 1){ 193*5595Srrh name = (*files[fi])->error_text[0]; 194*5595Srrh spread = files[fi+1] - files[fi]; 195*5595Srrh fprintf(stdout, terse 196*5595Srrh ? "\"%s\" has %d error%s, " 197*5595Srrh : "\nFile \"%s\" has %d error%s.\n" 198*5595Srrh , 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 */ 204*5595Srrh ntrueerrors = 0; 205*5595Srrh EITERATE(erpp, files, fi){ 2061460Sroot errorp = *erpp; 2071460Sroot if (errorp->error_e_class == C_TRUE) 2081460Sroot ntrueerrors++; 2091460Sroot } 210*5595Srrh fprintf(stdout, terse 211*5595Srrh ? "insert %d\n" 212*5595Srrh : "\t%d of these errors can be inserted into the file.\n", 2131460Sroot ntrueerrors); 2141460Sroot 215*5595Srrh hackfile(name, files, fi, ntrueerrors); 216*5595Srrh } 2171460Sroot scribbled = FALSE; 218*5595Srrh n_pissed_on = 0; 219*5595Srrh FILEITERATE(fi, 1){ 220*5595Srrh scribbled |= touchedfiles[fi]; 2211460Sroot n_pissed_on++; 2221460Sroot } 2231460Sroot if (scribbled){ 2241460Sroot /* 2251460Sroot * Construct an execv argument 2261460Sroot */ 227*5595Srrh execvarg(n_pissed_on, r_edargc, r_edargv); 2281460Sroot return(TRUE); 2291460Sroot } else { 230*5595Srrh if (!terse) 231*5595Srrh fprintf(stdout, "You didn't touch any files.\n"); 2321460Sroot return(FALSE); 2331460Sroot } 234*5595Srrh } 2351460Sroot 236*5595Srrh hackfile(name, files, ix, nerrors) 237*5595Srrh char *name; 238*5595Srrh Eptr **files; 239*5595Srrh int ix; 240*5595Srrh { 241*5595Srrh boolean previewed; 242*5595Srrh int errordest; /* where errors go*/ 243*5595Srrh 244*5595Srrh previewed = preview(name, nerrors, files, ix); 245*5595Srrh 246*5595Srrh errordest = settotouch(name); 247*5595Srrh 248*5595Srrh if (errordest != TOSTDOUT) 249*5595Srrh touchedfiles[ix] = TRUE; 250*5595Srrh 251*5595Srrh if (previewed && (errordest == TOSTDOUT)) 252*5595Srrh return; 253*5595Srrh 254*5595Srrh diverterrors(name, errordest, files, ix, previewed, nerrors); 255*5595Srrh 256*5595Srrh if (errordest == TOTHEFILE) 257*5595Srrh writetouched(); 258*5595Srrh } 259*5595Srrh 260*5595Srrh boolean preview(name, nerrors, files, ix) 261*5595Srrh char *name; 262*5595Srrh int nerrors; 263*5595Srrh Eptr **files; 264*5595Srrh int ix; 265*5595Srrh { 266*5595Srrh int back; 267*5595Srrh reg Eptr *erpp; 268*5595Srrh 269*5595Srrh if (!oktotouch(name)) 270*5595Srrh return(false); 271*5595Srrh if (nerrors <= 0) 272*5595Srrh return(false); 273*5595Srrh back = false; 274*5595Srrh if(query){ 275*5595Srrh switch(inquire(terse 276*5595Srrh ? "Preview? " 277*5595Srrh : "Do you want to preview the errors first? ")){ 278*5595Srrh case Q_YES: 279*5595Srrh case Q_yes: 280*5595Srrh back = true; 281*5595Srrh EITERATE(erpp, files, ix){ 282*5595Srrh errorprint(stdout, *erpp, TRUE); 283*5595Srrh } 284*5595Srrh if (!terse) 285*5595Srrh fprintf(stdout, "\n"); 286*5595Srrh default: 287*5595Srrh break; 288*5595Srrh } 289*5595Srrh } 290*5595Srrh return(back); 291*5595Srrh } 292*5595Srrh 293*5595Srrh int settotouch(name) 294*5595Srrh char *name; 295*5595Srrh { 296*5595Srrh int dest = TOSTDOUT; 297*5595Srrh 298*5595Srrh if (query){ 299*5595Srrh switch(touchstatus = inquire(terse 300*5595Srrh ? "Touch? " 301*5595Srrh : "Do you want to touch file \"%s\"? ", 302*5595Srrh name)){ 303*5595Srrh case Q_NO: 304*5595Srrh case Q_no: 305*5595Srrh return(dest); 306*5595Srrh default: 307*5595Srrh break; 308*5595Srrh } 309*5595Srrh } 310*5595Srrh 311*5595Srrh switch(probethisfile(name)){ 312*5595Srrh case F_NOTREAD: 313*5595Srrh dest = TOSTDOUT; 314*5595Srrh fprintf(stdout, terse 315*5595Srrh ? "\"%s\" unreadable\n" 316*5595Srrh : "File \"%s\" is unreadable\n", 317*5595Srrh name); 318*5595Srrh break; 319*5595Srrh case F_NOTWRITE: 320*5595Srrh dest = TOSTDOUT; 321*5595Srrh fprintf(stdout, terse 322*5595Srrh ? "\"%s\" unwritable\n" 323*5595Srrh : "File \"%s\" is unwritable\n", 324*5595Srrh name); 325*5595Srrh break; 326*5595Srrh case F_NOTEXIST: 327*5595Srrh dest = TOSTDOUT; 328*5595Srrh fprintf(stdout, terse 329*5595Srrh ? "\"%s\" not found\n" 330*5595Srrh : "Can't find file \"%s\" to insert error messages into.\n", 331*5595Srrh name); 332*5595Srrh break; 333*5595Srrh default: 334*5595Srrh dest = edit(name) ? TOSTDOUT : TOTHEFILE; 335*5595Srrh break; 336*5595Srrh } 337*5595Srrh return(dest); 338*5595Srrh } 339*5595Srrh 340*5595Srrh diverterrors(name, dest, files, ix, previewed, nterrors) 341*5595Srrh char *name; 342*5595Srrh int dest; 343*5595Srrh Eptr **files; 344*5595Srrh int ix; 345*5595Srrh boolean previewed; 346*5595Srrh int nterrors; 347*5595Srrh { 348*5595Srrh int nerrors; 349*5595Srrh reg Eptr *erpp; 350*5595Srrh reg Eptr errorp; 351*5595Srrh 352*5595Srrh nerrors = files[ix+1] - files[ix]; 353*5595Srrh 354*5595Srrh if ( (nerrors != nterrors) 355*5595Srrh && (!previewed) ){ 356*5595Srrh fprintf(stdout, terse 357*5595Srrh ? "Uninserted errors\n" 358*5595Srrh : ">>Uninserted errors for file \"%s\" follow.\n", 359*5595Srrh name); 360*5595Srrh } 361*5595Srrh 362*5595Srrh EITERATE(erpp, files, ix){ 363*5595Srrh errorp = *erpp; 364*5595Srrh if (errorp->error_e_class != C_TRUE){ 365*5595Srrh if (previewed || touchstatus == Q_NO) 366*5595Srrh continue; 367*5595Srrh errorprint(stdout, errorp, TRUE); 368*5595Srrh continue; 369*5595Srrh } 370*5595Srrh switch (dest){ 371*5595Srrh case TOSTDOUT: 372*5595Srrh if (previewed || touchstatus == Q_NO) 373*5595Srrh continue; 374*5595Srrh errorprint(stdout,errorp, TRUE); 375*5595Srrh break; 376*5595Srrh case TOTHEFILE: 377*5595Srrh insert(errorp->error_line); 378*5595Srrh text(errorp, FALSE); 379*5595Srrh break; 380*5595Srrh } 381*5595Srrh } 382*5595Srrh } 383*5595Srrh 384*5595Srrh int oktotouch(filename) 3851460Sroot char *filename; 3861460Sroot { 3871460Sroot extern char *suffixlist; 388*5595Srrh reg char *src; 389*5595Srrh reg char *pat; 3901460Sroot char *osrc; 3911460Sroot 3921460Sroot pat = suffixlist; 3931460Sroot if (pat == 0) 3941460Sroot return(0); 3951460Sroot if (*pat == '*') 3961460Sroot return(1); 3971460Sroot while (*pat++ != '.') 3981460Sroot continue; 3991460Sroot --pat; /* point to the period */ 4001460Sroot 4011460Sroot for (src = &filename[strlen(filename)], --src; 4021460Sroot (src > filename) && (*src != '.'); --src) 4031460Sroot continue; 4041460Sroot if (*src != '.') 4051460Sroot return(0); 4061460Sroot 4071460Sroot for (src++, pat++, osrc = src; *src && *pat; src = osrc, pat++){ 4081460Sroot for (; *src /* not at end of the source */ 4091460Sroot && *pat /* not off end of pattern */ 4101460Sroot && *pat != '.' /* not off end of sub pattern */ 4111460Sroot && *pat != '*' /* not wild card */ 4121460Sroot && *src == *pat; /* and equal... */ 4131460Sroot src++, pat++) 4141460Sroot continue; 4151460Sroot if (*src == 0 && (*pat == 0 || *pat == '.' || *pat == '*')) 4161460Sroot return(1); 4171460Sroot if (*src != 0 && *pat == '*') 4181460Sroot return(1); 4191460Sroot while (*pat && *pat != '.') 4201460Sroot pat++; 4211460Sroot if (! *pat) 4221460Sroot return(0); 4231460Sroot } 4241460Sroot return(0); 4251460Sroot } 426*5595Srrh /* 427*5595Srrh * Construct an execv argument 428*5595Srrh * We need 1 argument for the editor's name 429*5595Srrh * We need 1 argument for the initial search string 430*5595Srrh * We need n_pissed_on arguments for the file names 431*5595Srrh * We need 1 argument that is a null for execv. 432*5595Srrh * The caller fills in the editor's name. 433*5595Srrh * We fill in the initial search string. 434*5595Srrh * We fill in the arguments, and the null. 435*5595Srrh */ 436*5595Srrh execvarg(n_pissed_on, r_argc, r_argv) 437*5595Srrh int n_pissed_on; 438*5595Srrh int *r_argc; 439*5595Srrh char ***r_argv; 440*5595Srrh { 441*5595Srrh Eptr p; 442*5595Srrh char *sep; 443*5595Srrh int fi; 4441460Sroot 445*5595Srrh (*r_argv) = (char **)Calloc(n_pissed_on + 3, sizeof(char *)); 446*5595Srrh (*r_argc) = n_pissed_on + 2; 447*5595Srrh (*r_argv)[1] = "+1;/###/"; 448*5595Srrh n_pissed_on = 2; 449*5595Srrh if (!terse){ 450*5595Srrh fprintf(stdout, "You touched file(s):"); 451*5595Srrh sep = " "; 452*5595Srrh } 453*5595Srrh FILEITERATE(fi, 1){ 454*5595Srrh if (!touchedfiles[fi]) 455*5595Srrh continue; 456*5595Srrh p = *(files[fi]); 457*5595Srrh if (!terse){ 458*5595Srrh fprintf(stdout,"%s\"%s\"", sep, p->error_text[0]); 459*5595Srrh sep = ", "; 460*5595Srrh } 461*5595Srrh (*r_argv)[n_pissed_on++] = p->error_text[0]; 462*5595Srrh } 463*5595Srrh if (!terse) 464*5595Srrh fprintf(stdout, "\n"); 465*5595Srrh (*r_argv)[n_pissed_on] = 0; 466*5595Srrh } 467*5595Srrh 4681460Sroot FILE *o_touchedfile; /* the old file */ 4691460Sroot FILE *n_touchedfile; /* the new file */ 4701460Sroot char *o_name; 4711460Sroot char n_name[32]; 4721460Sroot char *canon_name = "ErrorXXXXXX"; 4731460Sroot int o_lineno; 4741460Sroot int n_lineno; 4751460Sroot boolean tempfileopen = FALSE; 4761460Sroot /* 4771460Sroot * open the file; guaranteed to be both readable and writable 4781460Sroot * Well, if it isn't, then return TRUE if something failed 4791460Sroot */ 4801460Sroot boolean edit(name) 4811460Sroot char *name; 4821460Sroot { 4831460Sroot o_name = name; 4841460Sroot if ( (o_touchedfile = fopen(name, "r")) == NULL){ 4851460Sroot fprintf(stderr, "%s: Can't open file \"%s\" to touch (read).\n", 4861460Sroot processname, name); 4871460Sroot return(TRUE); 4881460Sroot } 489*5595Srrh (void)strcpy(n_name, canon_name); 490*5595Srrh (void)mktemp(n_name); 4911460Sroot if ( (n_touchedfile = fopen(n_name, "w")) == NULL){ 4921460Sroot fprintf(stderr,"%s: Can't open file \"%s\" to touch (write).\n", 4931460Sroot processname, name); 4941460Sroot return(TRUE); 4951460Sroot } 4961460Sroot tempfileopen = TRUE; 4971460Sroot n_lineno = 0; 4981460Sroot o_lineno = 0; 4991460Sroot return(FALSE); 5001460Sroot } 5011460Sroot /* 5021460Sroot * Position to the line (before, after) the line given by place 5031460Sroot */ 504*5595Srrh char edbuf[BUFSIZ]; 5051460Sroot insert(place) 5061460Sroot int place; 5071460Sroot { 5081460Sroot --place; /* always insert messages before the offending line*/ 5091460Sroot for(; o_lineno < place; o_lineno++, n_lineno++){ 510*5595Srrh if(fgets(edbuf, BUFSIZ, o_touchedfile) == NULL) 5111460Sroot return; 512*5595Srrh fputs(edbuf, n_touchedfile); 5131460Sroot } 5141460Sroot } 5151460Sroot 516*5595Srrh text(p, use_all) 517*5595Srrh reg Eptr p; 518*5595Srrh boolean use_all; 5191460Sroot { 5201460Sroot int offset = use_all ? 0 : 2; 521*5595Srrh 522*5595Srrh fputs(lang_table[p->error_language].lang_incomment, n_touchedfile); 5231460Sroot fprintf(n_touchedfile, "%d [%s] ", 524*5595Srrh p->error_line, 525*5595Srrh lang_table[p->error_language].lang_name); 526*5595Srrh wordvprint(n_touchedfile, p->error_lgtext-offset, p->error_text+offset); 527*5595Srrh fputs(lang_table[p->error_language].lang_outcomment,n_touchedfile); 5281460Sroot n_lineno++; 5291460Sroot } 5301460Sroot 5311460Sroot writetouched() 5321460Sroot { 533*5595Srrh int nread; 534*5595Srrh 535*5595Srrh while((nread = fread(edbuf, 1, sizeof(edbuf), o_touchedfile)) != NULL){ 536*5595Srrh fwrite(edbuf, 1, nread, n_touchedfile); 5371460Sroot } 5381460Sroot fclose(n_touchedfile); 5391460Sroot fclose(o_touchedfile); 5401460Sroot unlink(o_name); 541*5595Srrh link(n_name, o_name); 5421460Sroot unlink(n_name); 5431460Sroot tempfileopen = FALSE; 5441460Sroot } 545*5595Srrh 5461460Sroot onintr() 5471460Sroot { 548*5595Srrh switch(inquire(terse 549*5595Srrh ? "\nContinue? " 550*5595Srrh : "\nInterrupt: Do you want to continue? ")){ 551*5595Srrh case Q_YES: 552*5595Srrh case Q_yes: 5531460Sroot signal(SIGINT, onintr); 5541460Sroot return; 555*5595Srrh default: 556*5595Srrh if (tempfileopen) 557*5595Srrh writetouched(); 558*5595Srrh exit(1); 5591460Sroot } 560*5595Srrh /*NOTREACHED*/ 5611460Sroot } 562*5595Srrh 5631460Sroot errorprint(place, errorp, print_all) 5641460Sroot FILE *place; 565*5595Srrh Eptr errorp; 5661460Sroot boolean print_all; 5671460Sroot { 5681460Sroot int offset = print_all ? 0 : 2; 5691460Sroot 5701460Sroot if (errorp->error_e_class == C_IGNORE) 5711460Sroot return; 5721460Sroot fprintf(place, "[%s] ", lang_table[errorp->error_language].lang_name); 5731460Sroot wordvprint(place,errorp->error_lgtext-offset,errorp->error_text+offset); 5741460Sroot putc('\n', place); 5751460Sroot } 5761460Sroot 577*5595Srrh int inquire(fmt, a1, a2) 5781460Sroot char *fmt; 5791460Sroot /*VARARGS1*/ 5801460Sroot { 5811460Sroot char buffer[128]; 5821460Sroot for(;;){ 5831460Sroot do{ 5841460Sroot fflush(stdout); 5851460Sroot fprintf(stderr, fmt, a1, a2); 5861460Sroot fflush(stderr); 5871460Sroot } while (fgets(buffer, 127, queryfile) == NULL); 588*5595Srrh switch(buffer[0]){ 589*5595Srrh case 'Y': return(Q_YES); 590*5595Srrh case 'y': return(Q_yes); 591*5595Srrh case 'N': return(Q_NO); 592*5595Srrh case 'n': return(Q_no); 593*5595Srrh default: fprintf(stderr, "Yes or No only!\n"); 594*5595Srrh } 5951460Sroot } 5961460Sroot } 5971460Sroot 598*5595Srrh int probethisfile(name) 599*5595Srrh char *name; 6001460Sroot { 6011460Sroot struct stat statbuf; 602*5595Srrh if (stat(name, &statbuf) < 0) 603*5595Srrh return(F_NOTEXIST); 604*5595Srrh if((statbuf.st_mode & S_IREAD) == 0) 605*5595Srrh return(F_NOTREAD); 606*5595Srrh if((statbuf.st_mode & S_IWRITE) == 0) 607*5595Srrh return(F_NOTWRITE); 608*5595Srrh return(F_TOUCHIT); 6091460Sroot } 610