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

unix.superglobalmegacorp.com

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