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

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

unix.superglobalmegacorp.com

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