Annotation of 43BSDReno/contrib/patch/inp.c, revision 1.1

1.1     ! root        1: /* $Header: inp.c,v 2.0 86/09/17 15:37:02 lwall Exp $
        !             2:  *
        !             3:  * $Log:       inp.c,v $
        !             4:  * Revision 2.0  86/09/17  15:37:02  lwall
        !             5:  * Baseline for netwide release.
        !             6:  * 
        !             7:  */
        !             8: 
        !             9: #include "EXTERN.h"
        !            10: #include "common.h"
        !            11: #include "util.h"
        !            12: #include "pch.h"
        !            13: #include "INTERN.h"
        !            14: #include "inp.h"
        !            15: 
        !            16: /* Input-file-with-indexable-lines abstract type */
        !            17: 
        !            18: static long i_size;                    /* size of the input file */
        !            19: static char *i_womp;                   /* plan a buffer for entire file */
        !            20: static char **i_ptr;                   /* pointers to lines in i_womp */
        !            21: 
        !            22: static int tifd = -1;                  /* plan b virtual string array */
        !            23: static char *tibuf[2];                 /* plan b buffers */
        !            24: static LINENUM tiline[2] = {-1, -1};   /* 1st line in each buffer */
        !            25: static LINENUM lines_per_buf;          /* how many lines per buffer */
        !            26: static int tireclen;                   /* length of records in tmp file */
        !            27: 
        !            28: /* New patch--prepare to edit another file. */
        !            29: 
        !            30: void
        !            31: re_input()
        !            32: {
        !            33:     if (using_plan_a) {
        !            34:        i_size = 0;
        !            35: #ifndef lint
        !            36:        if (i_ptr != Null(char**))
        !            37:            free((char *)i_ptr);
        !            38: #endif
        !            39:        if (i_womp != Nullch)
        !            40:            free(i_womp);
        !            41:        i_womp = Nullch;
        !            42:        i_ptr = Null(char **);
        !            43:     }
        !            44:     else {
        !            45:        using_plan_a = TRUE;            /* maybe the next one is smaller */
        !            46:        Close(tifd);
        !            47:        tifd = -1;
        !            48:        free(tibuf[0]);
        !            49:        free(tibuf[1]);
        !            50:        tibuf[0] = tibuf[1] = Nullch;
        !            51:        tiline[0] = tiline[1] = -1;
        !            52:        tireclen = 0;
        !            53:     }
        !            54: }
        !            55: 
        !            56: /* Constuct the line index, somehow or other. */
        !            57: 
        !            58: void
        !            59: scan_input(filename)
        !            60: char *filename;
        !            61: {
        !            62:     if (!plan_a(filename))
        !            63:        plan_b(filename);
        !            64:     if (verbose) {
        !            65:        say3("Patching file %s using Plan %s...\n", filename,
        !            66:          (using_plan_a ? "A" : "B") );
        !            67:     }
        !            68: }
        !            69: 
        !            70: /* Try keeping everything in memory. */
        !            71: 
        !            72: bool
        !            73: plan_a(filename)
        !            74: char *filename;
        !            75: {
        !            76:     int ifd;
        !            77:     Reg1 char *s;
        !            78:     Reg2 LINENUM iline;
        !            79: 
        !            80:     if (ok_to_create_file && stat(filename, &filestat) < 0) {
        !            81:        if (verbose)
        !            82:            say2("(Creating file %s...)\n",filename);
        !            83:        makedirs(filename, TRUE);
        !            84:        close(creat(filename, 0666));
        !            85:     }
        !            86:     if (stat(filename, &filestat) < 0) {
        !            87:        Sprintf(buf, "RCS/%s%s", filename, RCSSUFFIX);
        !            88:        if (stat(buf, &filestat) >= 0 || stat(buf+4, &filestat) >= 0) {
        !            89:            Sprintf(buf, CHECKOUT, filename);
        !            90:            if (verbose)
        !            91:                say2("Can't find %s--attempting to check it out from RCS.\n",
        !            92:                    filename);
        !            93:            if (system(buf) || stat(filename, &filestat))
        !            94:                fatal2("Can't check out %s.\n", filename);
        !            95:        }
        !            96:        else {
        !            97:            Sprintf(buf, "SCCS/%s%s", SCCSPREFIX, filename);
        !            98:            if (stat(buf, &filestat) >= 0 || stat(buf+5, &filestat) >= 0) {
        !            99:                Sprintf(buf, GET, filename);
        !           100:                if (verbose)
        !           101:                    say2("Can't find %s--attempting to get it from SCCS.\n",
        !           102:                        filename);
        !           103:                if (system(buf) || stat(filename, &filestat))
        !           104:                    fatal2("Can't get %s.\n", filename);
        !           105:            }
        !           106:            else
        !           107:                fatal2("Can't find %s.\n", filename);
        !           108:        }
        !           109:     }
        !           110:     filemode = filestat.st_mode;
        !           111:     if ((filemode & S_IFMT) & ~S_IFREG)
        !           112:        fatal2("%s is not a normal file--can't patch.\n", filename);
        !           113:     i_size = filestat.st_size;
        !           114:     if (out_of_mem) {
        !           115:        set_hunkmax();          /* make sure dynamic arrays are allocated */
        !           116:        out_of_mem = FALSE;
        !           117:        return FALSE;                   /* force plan b because plan a bombed */
        !           118:     }
        !           119: #ifdef lint
        !           120:     i_womp = Nullch;
        !           121: #else
        !           122:     i_womp = malloc((MEM)(i_size+2));  /* lint says this may alloc less than */
        !           123:                                        /* i_size, but that's okay, I think. */
        !           124: #endif
        !           125:     if (i_womp == Nullch)
        !           126:        return FALSE;
        !           127:     if ((ifd = open(filename, 0)) < 0)
        !           128:        fatal2("Can't open file %s\n", filename);
        !           129: #ifndef lint
        !           130:     if (read(ifd, i_womp, (int)i_size) != i_size) {
        !           131:        Close(ifd);     /* probably means i_size > 15 or 16 bits worth */
        !           132:        free(i_womp);   /* at this point it doesn't matter if i_womp was */
        !           133:        return FALSE;   /*   undersized. */
        !           134:     }
        !           135: #endif
        !           136:     Close(ifd);
        !           137:     if (i_size && i_womp[i_size-1] != '\n')
        !           138:        i_womp[i_size++] = '\n';
        !           139:     i_womp[i_size] = '\0';
        !           140: 
        !           141:     /* count the lines in the buffer so we know how many pointers we need */
        !           142: 
        !           143:     iline = 0;
        !           144:     for (s=i_womp; *s; s++) {
        !           145:        if (*s == '\n')
        !           146:            iline++;
        !           147:     }
        !           148: #ifdef lint
        !           149:     i_ptr = Null(char**);
        !           150: #else
        !           151:     i_ptr = (char **)malloc((MEM)((iline + 2) * sizeof(char *)));
        !           152: #endif
        !           153:     if (i_ptr == Null(char **)) {      /* shucks, it was a near thing */
        !           154:        free((char *)i_womp);
        !           155:        return FALSE;
        !           156:     }
        !           157:     
        !           158:     /* now scan the buffer and build pointer array */
        !           159: 
        !           160:     iline = 1;
        !           161:     i_ptr[iline] = i_womp;
        !           162:     for (s=i_womp; *s; s++) {
        !           163:        if (*s == '\n')
        !           164:            i_ptr[++iline] = s+1;       /* these are NOT null terminated */
        !           165:     }
        !           166:     input_lines = iline - 1;
        !           167: 
        !           168:     /* now check for revision, if any */
        !           169: 
        !           170:     if (revision != Nullch) { 
        !           171:        if (!rev_in_string(i_womp)) {
        !           172:            if (force) {
        !           173:                if (verbose)
        !           174:                    say2("\
        !           175: Warning: this file doesn't appear to be the %s version--patching anyway.\n",
        !           176:                        revision);
        !           177:            }
        !           178:            else {
        !           179:                ask2("\
        !           180: This file doesn't appear to be the %s version--patch anyway? [n] ",
        !           181:                    revision);
        !           182:            if (*buf != 'y')
        !           183:                fatal1("Aborted.\n");
        !           184:            }
        !           185:        }
        !           186:        else if (verbose)
        !           187:            say2("Good.  This file appears to be the %s version.\n",
        !           188:                revision);
        !           189:     }
        !           190:     return TRUE;                       /* plan a will work */
        !           191: }
        !           192: 
        !           193: /* Keep (virtually) nothing in memory. */
        !           194: 
        !           195: void
        !           196: plan_b(filename)
        !           197: char *filename;
        !           198: {
        !           199:     Reg3 FILE *ifp;
        !           200:     Reg1 int i = 0;
        !           201:     Reg2 int maxlen = 1;
        !           202:     Reg4 bool found_revision = (revision == Nullch);
        !           203: 
        !           204:     using_plan_a = FALSE;
        !           205:     if ((ifp = fopen(filename, "r")) == Nullfp)
        !           206:        fatal2("Can't open file %s\n", filename);
        !           207:     if ((tifd = creat(TMPINNAME, 0666)) < 0)
        !           208:        fatal2("Can't open file %s\n", TMPINNAME);
        !           209:     while (fgets(buf, sizeof buf, ifp) != Nullch) {
        !           210:        if (revision != Nullch && !found_revision && rev_in_string(buf))
        !           211:            found_revision = TRUE;
        !           212:        if ((i = strlen(buf)) > maxlen)
        !           213:            maxlen = i;                 /* find longest line */
        !           214:     }
        !           215:     if (revision != Nullch) {
        !           216:        if (!found_revision) {
        !           217:            if (force) {
        !           218:                if (verbose)
        !           219:                    say2("\
        !           220: Warning: this file doesn't appear to be the %s version--patching anyway.\n",
        !           221:                        revision);
        !           222:            }
        !           223:            else {
        !           224:                ask2("\
        !           225: This file doesn't appear to be the %s version--patch anyway? [n] ",
        !           226:                    revision);
        !           227:                if (*buf != 'y')
        !           228:                    fatal1("Aborted.\n");
        !           229:            }
        !           230:        }
        !           231:        else if (verbose)
        !           232:            say2("Good.  This file appears to be the %s version.\n",
        !           233:                revision);
        !           234:     }
        !           235:     Fseek(ifp, 0L, 0);         /* rewind file */
        !           236:     lines_per_buf = BUFFERSIZE / maxlen;
        !           237:     tireclen = maxlen;
        !           238:     tibuf[0] = malloc((MEM)(BUFFERSIZE + 1));
        !           239:     tibuf[1] = malloc((MEM)(BUFFERSIZE + 1));
        !           240:     if (tibuf[1] == Nullch)
        !           241:        fatal1("Can't seem to get enough memory.\n");
        !           242:     for (i=1; ; i++) {
        !           243:        if (! (i % lines_per_buf))      /* new block */
        !           244:            if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
        !           245:                fatal1("patch: can't write temp file.\n");
        !           246:        if (fgets(tibuf[0] + maxlen * (i%lines_per_buf), maxlen + 1, ifp)
        !           247:          == Nullch) {
        !           248:            input_lines = i - 1;
        !           249:            if (i % lines_per_buf)
        !           250:                if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
        !           251:                    fatal1("patch: can't write temp file.\n");
        !           252:            break;
        !           253:        }
        !           254:     }
        !           255:     Fclose(ifp);
        !           256:     Close(tifd);
        !           257:     if ((tifd = open(TMPINNAME, 0)) < 0) {
        !           258:        fatal2("Can't reopen file %s\n", TMPINNAME);
        !           259:     }
        !           260: }
        !           261: 
        !           262: /* Fetch a line from the input file, \n terminated, not necessarily \0. */
        !           263: 
        !           264: char *
        !           265: ifetch(line,whichbuf)
        !           266: Reg1 LINENUM line;
        !           267: int whichbuf;                          /* ignored when file in memory */
        !           268: {
        !           269:     if (line < 1 || line > input_lines)
        !           270:        return "";
        !           271:     if (using_plan_a)
        !           272:        return i_ptr[line];
        !           273:     else {
        !           274:        LINENUM offline = line % lines_per_buf;
        !           275:        LINENUM baseline = line - offline;
        !           276: 
        !           277:        if (tiline[0] == baseline)
        !           278:            whichbuf = 0;
        !           279:        else if (tiline[1] == baseline)
        !           280:            whichbuf = 1;
        !           281:        else {
        !           282:            tiline[whichbuf] = baseline;
        !           283: #ifndef lint           /* complains of long accuracy */
        !           284:            Lseek(tifd, (long)baseline / lines_per_buf * BUFFERSIZE, 0);
        !           285: #endif
        !           286:            if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0)
        !           287:                fatal2("Error reading tmp file %s.\n", TMPINNAME);
        !           288:        }
        !           289:        return tibuf[whichbuf] + (tireclen*offline);
        !           290:     }
        !           291: }
        !           292: 
        !           293: /* True if the string argument contains the revision number we want. */
        !           294: 
        !           295: bool
        !           296: rev_in_string(string)
        !           297: char *string;
        !           298: {
        !           299:     Reg1 char *s;
        !           300:     Reg2 int patlen;
        !           301: 
        !           302:     if (revision == Nullch)
        !           303:        return TRUE;
        !           304:     patlen = strlen(revision);
        !           305:     for (s = string; *s; s++) {
        !           306:        if (isspace(*s) && strnEQ(s+1, revision, patlen) && 
        !           307:                isspace(s[patlen+1] )) {
        !           308:            return TRUE;
        !           309:        }
        !           310:     }
        !           311:     return FALSE;
        !           312: }
        !           313: 

unix.superglobalmegacorp.com

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