Annotation of 42BSD/ucb/error/errortouch.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.