Annotation of coherent/g/usr/bin/vi/tmp.c, revision 1.1

1.1     ! root        1: /* tmp.c */
        !             2: 
        !             3: /* Author:
        !             4:  *     Steve Kirkendall
        !             5:  *     14407 SW Teal Blvd. #C
        !             6:  *     Beaverton, OR 97005
        !             7:  *     [email protected]
        !             8:  */
        !             9: 
        !            10: 
        !            11: /* This file contains functions which create & readback a TMPFILE */
        !            12: 
        !            13: 
        !            14: #include "config.h"
        !            15: #include "vi.h"
        !            16: #if TOS
        !            17: # include <stat.h>
        !            18: #else
        !            19: # if OSK
        !            20: #  include "osk.h"
        !            21: # else
        !            22: #  if AMIGA
        !            23: #   include "amistat.h"
        !            24: #  else
        !            25: #   include <sys/stat.h>
        !            26: #  endif
        !            27: # endif
        !            28: #endif
        !            29: #if TURBOC
        !            30: # include <process.h>
        !            31: #endif
        !            32: 
        !            33: #ifndef NO_MODELINES
        !            34: static void do_modelines(l, stop)
        !            35:        long    l;      /* line number to start at */
        !            36:        long    stop;   /* line number to stop at */
        !            37: {
        !            38:        char    *str;   /* used to scan through the line */
        !            39:        char    *start; /* points to the start of the line */
        !            40:        char    buf[80];
        !            41: 
        !            42:        /* if modelines are disabled, then do nothing */
        !            43:        if (!*o_modelines)
        !            44:        {
        !            45:                return;
        !            46:        }
        !            47: 
        !            48:        /* for each line... */
        !            49:        for (; l <= stop; l++)
        !            50:        {
        !            51:                /* for each position in the line.. */
        !            52:                for (str = fetchline(l); *str; str++)
        !            53:                {
        !            54:                        /* if it is the start of a modeline command... */
        !            55:                        if ((str[0] == 'e' && str[1] == 'x'
        !            56:                          || str[0] == 'v' && str[1] == 'i')
        !            57:                          && str[2] == ':')
        !            58:                        {
        !            59:                                start = str += 3;
        !            60: 
        !            61:                                /* find the end */
        !            62:                                for (str = start + strlen(start); *--str != ':'; )
        !            63:                                {
        !            64:                                }
        !            65: 
        !            66:                                /* if it is a well-formed modeline, execute it */
        !            67:                                if (str > start && str - start < sizeof buf)
        !            68:                                {
        !            69:                                        strncpy(buf, start, (int)(str - start));
        !            70:                                        exstring(buf, str - start, '\\');
        !            71:                                        break;
        !            72:                                }
        !            73:                        }
        !            74:                }
        !            75:        }
        !            76: }
        !            77: #endif
        !            78: 
        !            79: 
        !            80: /* The FAIL() macro prints an error message and then exits. */
        !            81: #define FAIL(why,arg)  mode = MODE_EX; msg(why, arg); endwin(); exit(9)
        !            82: 
        !            83: /* This is the name of the temp file */
        !            84: static char    tmpname[80];
        !            85: 
        !            86: /* This function creates the temp file and copies the original file into it.
        !            87:  * Returns if successful, or stops execution if it fails.
        !            88:  */
        !            89: int tmpstart(filename)
        !            90:        char            *filename; /* name of the original file */
        !            91: {
        !            92:        int             origfd; /* fd used for reading the original file */
        !            93:        struct stat     statb;  /* stat buffer, used to examine inode */
        !            94:        REG BLK         *this;  /* pointer to the current block buffer */
        !            95:        REG BLK         *next;  /* pointer to the next block buffer */
        !            96:        int             inbuf;  /* number of characters in a buffer */
        !            97:        int             nread;  /* number of bytes read */
        !            98:        REG int         j, k;
        !            99:        int             i;
        !           100:        long            nbytes;
        !           101: 
        !           102:        /* switching to a different file certainly counts as a change */
        !           103:        changes++;
        !           104:        redraw(MARK_UNSET, FALSE);
        !           105: 
        !           106:        /* open the original file for reading */
        !           107:        *origname = '\0';
        !           108:        if (filename && *filename)
        !           109:        {
        !           110:                strcpy(origname, filename);
        !           111:                origfd = open(origname, O_RDONLY);
        !           112:                if (origfd < 0 && errno != ENOENT)
        !           113:                {
        !           114:                        msg("Can't open \"%s\"", origname);
        !           115:                        return tmpstart("");
        !           116:                }
        !           117:                if (origfd >= 0)
        !           118:                {
        !           119:                        if (stat(origname, &statb) < 0)
        !           120:                        {
        !           121:                                FAIL("Can't stat \"%s\"", origname);
        !           122:                        }
        !           123: #if TOS
        !           124:                        if (origfd >= 0 && (statb.st_mode & S_IJDIR))
        !           125: #else
        !           126: # if OSK
        !           127:                        if (origfd >= 0 && (statb.st_mode & S_IFDIR))
        !           128: # else
        !           129:                        if (origfd >= 0 && (statb.st_mode & S_IFMT) != S_IFREG)
        !           130: # endif
        !           131: #endif
        !           132:                        {
        !           133:                                msg("\"%s\" is not a regular file", origname);
        !           134:                                return tmpstart("");
        !           135:                        }
        !           136:                }
        !           137:                else
        !           138:                {
        !           139:                        stat(".", &statb);
        !           140:                }
        !           141:                if (origfd >= 0)
        !           142:                {
        !           143:                        origtime = statb.st_mtime;
        !           144: #if OSK
        !           145:                        if (*o_readonly || !(statb.st_mode &
        !           146:                                  ((getuid() >> 16) == 0 ? S_IOWRITE | S_IWRITE :
        !           147:                                  ((statb.st_gid != (getuid() >> 16) ? S_IOWRITE : S_IWRITE)))))
        !           148: #endif
        !           149: #if AMIGA || MSDOS
        !           150:                        if (*o_readonly || !(statb.st_mode & S_IWRITE))
        !           151: #endif
        !           152: #if TOS
        !           153: # ifdef __GNUC__ 
        !           154:                        if (*o_readonly || !(statb.st_mode & S_IWRITE))
        !           155: # else
        !           156:                        if (*o_readonly || (statb.st_mode & S_IJRON))
        !           157: # endif
        !           158: #endif
        !           159: #if ANY_UNIX
        !           160:                        if (*o_readonly || !(statb.st_mode &
        !           161:                                  ((geteuid() == 0) ? 0222 :
        !           162:                                  ((statb.st_uid != geteuid() ? 0022 : 0200)))))
        !           163: #endif
        !           164: #if VMS
        !           165:                        if (*o_readonly)
        !           166: #endif
        !           167:                        {
        !           168:                                setflag(file, READONLY);
        !           169:                        }
        !           170:                }
        !           171:                else
        !           172:                {
        !           173:                        origtime = 0L;
        !           174:                }
        !           175:        }
        !           176:        else
        !           177:        {
        !           178:                setflag(file, NOFILE);
        !           179:                origfd = -1;
        !           180:                origtime = 0L;
        !           181:                stat(".", &statb);
        !           182:        }
        !           183: 
        !           184:        /* make a name for the tmp file */
        !           185:        tmpnum++;
        !           186: #if MSDOS || TOS
        !           187:        /* MS-Dos doesn't allow multiple slashes, but supports drives
        !           188:         * with current directories.
        !           189:         * This relies on TMPNAME beginning with "%s\\"!!!!
        !           190:         */
        !           191:        strcpy(tmpname, o_directory);
        !           192:        if ((i = strlen(tmpname)) && !strchr(":/\\", tmpname[i-1]))
        !           193:                tmpname[i++]=SLASH;
        !           194:        sprintf(tmpname+i, TMPNAME+3, getpid(), tmpnum);
        !           195: #else
        !           196:        sprintf(tmpname, TMPNAME, o_directory, getpid(), tmpnum);
        !           197: #endif
        !           198: 
        !           199:        /* make sure nobody else is editing the same file */
        !           200:        if (access(tmpname, 0) == 0)
        !           201:        {
        !           202:                FAIL("Temp file \"%s\" already exists?", tmpname);
        !           203:        }
        !           204: 
        !           205:        /* create the temp file */
        !           206: #if ANY_UNIX
        !           207:        close(creat(tmpname, 0600));            /* only we can read it */
        !           208: #else
        !           209:        close(creat(tmpname, FILEPERMS));       /* anybody body can read it, alas */
        !           210: #endif
        !           211:        tmpfd = open(tmpname, O_RDWR | O_BINARY);
        !           212:        if (tmpfd < 0)
        !           213:        {
        !           214:                FAIL("Can't create temp file... Does directory \"%s\" exist?", o_directory);
        !           215:                return 1;
        !           216:        }
        !           217: 
        !           218:        /* allocate space for the header in the file */
        !           219:        write(tmpfd, hdr.c, (unsigned)BLKSIZE);
        !           220:        write(tmpfd, tmpblk.c, (unsigned)BLKSIZE);
        !           221: 
        !           222: #ifndef NO_RECYCLE
        !           223:        /* initialize the block allocator */
        !           224:        /* This must already be done here, before the first attempt
        !           225:         * to write to the new file! GB */
        !           226:        garbage();
        !           227: #endif
        !           228: 
        !           229:        /* initialize lnum[] */
        !           230:        for (i = 1; i < MAXBLKS; i++)
        !           231:        {
        !           232:                lnum[i] = INFINITY;
        !           233:        }
        !           234:        lnum[0] = 0;
        !           235: 
        !           236:        /* if there is no original file, then create a 1-line file */
        !           237:        if (origfd < 0)
        !           238:        {
        !           239:                hdr.n[0] = 0;   /* invalid inode# denotes new file */
        !           240: 
        !           241:                this = blkget(1);       /* get the new text block */
        !           242:                strcpy(this->c, "\n");  /* put a line in it */
        !           243: 
        !           244:                lnum[1] = 1L;   /* block 1 ends with line 1 */
        !           245:                nlines = 1L;    /* there is 1 line in the file */
        !           246:                nbytes = 1L;
        !           247: 
        !           248:                if (*origname)
        !           249:                {
        !           250:                        msg("\"%s\" [NEW FILE]  1 line, 1 char", origname);
        !           251:                }
        !           252:                else
        !           253:                {
        !           254:                        msg("\"[NO FILE]\"  1 line, 1 char");
        !           255:                }
        !           256:        }
        !           257:        else /* there is an original file -- read it in */
        !           258:        {
        !           259:                nbytes = nlines = 0;
        !           260: 
        !           261:                /* preallocate 1 "next" buffer */
        !           262:                i = 1;
        !           263:                next = blkget(i);
        !           264:                inbuf = 0;
        !           265: 
        !           266:                /* loop, moving blocks from orig to tmp */
        !           267:                for (;;)
        !           268:                {
        !           269:                        /* "next" buffer becomes "this" buffer */
        !           270:                        this = next;
        !           271: 
        !           272:                        /* read [more] text into this block */
        !           273:                        nread = tread(origfd, &this->c[inbuf], BLKSIZE - 1 - inbuf);
        !           274:                        if (nread < 0)
        !           275:                        {
        !           276:                                close(origfd);
        !           277:                                close(tmpfd);
        !           278:                                tmpfd = -1;
        !           279:                                unlink(tmpname);
        !           280:                                FAIL("Error reading \"%s\"", origname);
        !           281:                        }
        !           282: 
        !           283:                        /* convert NUL characters to something else */
        !           284:                        for (j = k = inbuf; k < inbuf + nread; k++)
        !           285:                        {
        !           286:                                if (!this->c[k])
        !           287:                                {
        !           288:                                        setflag(file, HADNUL);
        !           289:                                        this->c[j++] = 0x80;
        !           290:                                }
        !           291: #ifndef CRUNCH
        !           292:                                else if (*o_beautify && this->c[k] < ' ' && this->c[k] >= 1)
        !           293:                                {
        !           294:                                        if (this->c[k] == '\t'
        !           295:                                         || this->c[k] == '\n'
        !           296:                                         || this->c[k] == '\f')
        !           297:                                        {
        !           298:                                                this->c[j++] = this->c[k];
        !           299:                                        }
        !           300:                                        else if (this->c[k] == '\b')
        !           301:                                        {
        !           302:                                                /* delete '\b', but complain */
        !           303:                                                setflag(file, HADBS);
        !           304:                                        }
        !           305:                                        /* else silently delete control char */
        !           306:                                }
        !           307: #endif
        !           308:                                else
        !           309:                                {
        !           310:                                        this->c[j++] = this->c[k];
        !           311:                                }
        !           312:                        }
        !           313:                        inbuf = j;
        !           314: 
        !           315:                        /* if the buffer is empty, quit */
        !           316:                        if (inbuf == 0)
        !           317:                        {
        !           318:                                goto FoundEOF;
        !           319:                        }
        !           320: 
        !           321: #if MSDOS || TOS
        !           322: /* BAH! MS text mode read fills inbuf, then compresses eliminating \r
        !           323:    but leaving garbage at end of buf. The same is true for TURBOC. GB. */
        !           324: 
        !           325:                        memset(this->c + inbuf, '\0', BLKSIZE - inbuf);
        !           326: #endif
        !           327: 
        !           328:                        /* search backward for last newline */
        !           329:                        for (k = inbuf; --k >= 0 && this->c[k] != '\n';)
        !           330:                        {
        !           331:                        }
        !           332:                        if (k++ < 0)
        !           333:                        {
        !           334:                                if (inbuf >= BLKSIZE - 1)
        !           335:                                {
        !           336:                                        k = 80;
        !           337:                                }
        !           338:                                else
        !           339:                                {
        !           340:                                        k = inbuf;
        !           341:                                }
        !           342:                        }
        !           343: 
        !           344:                        /* allocate next buffer */
        !           345:                        next = blkget(++i);
        !           346: 
        !           347:                        /* move fragmentary last line to next buffer */
        !           348:                        inbuf -= k;
        !           349:                        for (j = 0; k < BLKSIZE; j++, k++)
        !           350:                        {
        !           351:                                next->c[j] = this->c[k];
        !           352:                                this->c[k] = 0;
        !           353:                        }
        !           354: 
        !           355:                        /* if necessary, add a newline to this buf */
        !           356:                        for (k = BLKSIZE - inbuf; --k >= 0 && !this->c[k]; )
        !           357:                        {
        !           358:                        }
        !           359:                        if (this->c[k] != '\n')
        !           360:                        {
        !           361:                                setflag(file, ADDEDNL);
        !           362:                                this->c[k + 1] = '\n';
        !           363:                        }
        !           364: 
        !           365:                        /* count the lines in this block */
        !           366:                        for (k = 0; k < BLKSIZE && this->c[k]; k++)
        !           367:                        {
        !           368:                                if (this->c[k] == '\n')
        !           369:                                {
        !           370:                                        nlines++;
        !           371:                                }
        !           372:                                nbytes++;
        !           373:                        }
        !           374:                        lnum[i - 1] = nlines;
        !           375:                }
        !           376: FoundEOF:
        !           377: 
        !           378:                /* if this is a zero-length file, add 1 line */
        !           379:                if (nlines == 0)
        !           380:                {
        !           381:                        this = blkget(1);       /* get the new text block */
        !           382:                        strcpy(this->c, "\n");  /* put a line in it */
        !           383: 
        !           384:                        lnum[1] = 1;    /* block 1 ends with line 1 */
        !           385:                        nlines = 1;     /* there is 1 line in the file */
        !           386:                        nbytes = 1;
        !           387:                }
        !           388: 
        !           389: #if MSDOS || TOS
        !           390:                /* each line has an extra CR that we didn't count yet */
        !           391:                nbytes += nlines;
        !           392: #endif
        !           393: 
        !           394:                /* report the number of lines in the file */
        !           395:                msg("\"%s\" %s %ld line%s, %ld char%s",
        !           396:                        origname,
        !           397:                        (tstflag(file, READONLY) ? "[READONLY]" : ""),
        !           398:                        nlines,
        !           399:                        nlines == 1 ? "" : "s",
        !           400:                        nbytes,
        !           401:                        nbytes == 1 ? "" : "s");
        !           402:        }
        !           403: 
        !           404:        /* initialize the cursor to start of line 1 */
        !           405:        cursor = MARK_FIRST;
        !           406: 
        !           407:        /* close the original file */
        !           408:        close(origfd);
        !           409: 
        !           410:        /* any other messages? */
        !           411:        if (tstflag(file, HADNUL))
        !           412:        {
        !           413:                msg("This file contained NULs.  They've been changed to \\x80 chars");
        !           414:        }
        !           415:        if (tstflag(file, ADDEDNL))
        !           416:        {
        !           417:                msg("Newline characters have been inserted to break up long lines");
        !           418:        }
        !           419: #ifndef CRUNCH
        !           420:        if (tstflag(file, HADBS))
        !           421:        {
        !           422:                msg("Backspace characters deleted due to ':set beautify'");
        !           423:        }
        !           424: #endif
        !           425: 
        !           426:        storename(origname);
        !           427: 
        !           428: #ifndef NO_MODELINES
        !           429:        if (nlines > 10)
        !           430:        {
        !           431:                do_modelines(1L, 5L);
        !           432:                do_modelines(nlines - 4L, nlines);
        !           433:        }
        !           434:        else
        !           435:        {
        !           436:                do_modelines(1L, nlines);
        !           437:        }
        !           438: #endif
        !           439: 
        !           440:        /* force all blocks out onto the disk, to support file recovery */
        !           441:        blksync();
        !           442: 
        !           443:        return 0;
        !           444: }
        !           445: 
        !           446: 
        !           447: 
        !           448: /* This function copies the temp file back onto an original file.
        !           449:  * Returns TRUE if successful, or FALSE if the file could NOT be saved.
        !           450:  */
        !           451: int tmpsave(filename, bang)
        !           452:        char    *filename;      /* the name to save it to */
        !           453:        int     bang;           /* forced write? */
        !           454: {
        !           455:        int             fd;     /* fd of the file we're writing to */
        !           456:        REG int         len;    /* length of a text block */
        !           457:        REG BLK         *this;  /* a text block */
        !           458:        long            bytes;  /* byte counter */
        !           459:        REG int         i;
        !           460: 
        !           461:        /* if no filename is given, assume the original file name */
        !           462:        if (!filename || !*filename)
        !           463:        {
        !           464:                filename = origname;
        !           465:        }
        !           466: 
        !           467:        /* if still no file name, then fail */
        !           468:        if (!*filename)
        !           469:        {
        !           470:                msg("Don't know a name for this file -- NOT WRITTEN");
        !           471:                return FALSE;
        !           472:        }
        !           473: 
        !           474:        /* can't rewrite a READONLY file */
        !           475:        if (!strcmp(filename, origname) && tstflag(file, READONLY) && !bang)
        !           476:        {
        !           477:                msg("\"%s\" [READONLY] -- NOT WRITTEN", filename);
        !           478:                return FALSE;
        !           479:        }
        !           480: 
        !           481:        /* open the file */
        !           482:        if (*filename == '>' && filename[1] == '>')
        !           483:        {
        !           484:                filename += 2;
        !           485:                while (*filename == ' ' || *filename == '\t')
        !           486:                {
        !           487:                        filename++;
        !           488:                }
        !           489: #ifdef O_APPEND
        !           490:                fd = open(filename, O_WRONLY|O_APPEND);
        !           491: #else
        !           492:                fd = open(filename, O_WRONLY);
        !           493:                lseek(fd, 0L, 2);
        !           494: #endif
        !           495:        }
        !           496:        else
        !           497:        {
        !           498:                /* either the file must not exist, or it must be the original
        !           499:                 * file, or we must have a bang, or "writeany" must be set.
        !           500:                 */
        !           501:                if (strcmp(filename, origname) && access(filename, 0) == 0 && !bang
        !           502: #ifndef CRUNCH
        !           503:                    && !*o_writeany
        !           504: #endif
        !           505:                                   )
        !           506:                {
        !           507:                        msg("File already exists - Use :w! to overwrite");
        !           508:                        return FALSE;
        !           509:                }
        !           510: #if VMS
        !           511:                /* Create a new VMS version of this file. */
        !           512:                { 
        !           513:                char *strrchr(), *ptr = strrchr(filename,';');
        !           514:                if (ptr) *ptr = '\0';  /* Snip off any ;number in the name */
        !           515:                }
        !           516: #endif
        !           517:                fd = creat(filename, FILEPERMS);
        !           518:        }
        !           519:        if (fd < 0)
        !           520:        {
        !           521:                msg("Can't write to \"%s\" -- NOT WRITTEN", filename);
        !           522:                return FALSE;
        !           523:        }
        !           524: 
        !           525:        /* write each text block to the file */
        !           526:        bytes = 0L;
        !           527:        for (i = 1; i < MAXBLKS && (this = blkget(i)) && this->c[0]; i++)
        !           528:        {
        !           529:                for (len = 0; len < BLKSIZE && this->c[len]; len++)
        !           530:                {
        !           531:                }
        !           532:                if (twrite(fd, this->c, len) < len)
        !           533:                {
        !           534:                        msg("Trouble writing to \"%s\"", filename);
        !           535:                        if (!strcmp(filename, origname))
        !           536:                        {
        !           537:                                setflag(file, MODIFIED);
        !           538:                        }
        !           539:                        close(fd);
        !           540:                        return FALSE;
        !           541:                }
        !           542:                bytes += len;
        !           543:        }
        !           544: 
        !           545:        /* reset the "modified" flag, but not the "undoable" flag */
        !           546:        clrflag(file, MODIFIED);
        !           547:        significant = FALSE;
        !           548:        if (!strcmp(origname, filename))
        !           549:        {
        !           550:                exitcode |= 1;
        !           551:        }
        !           552: 
        !           553:        /* report lines & characters */
        !           554: #if MSDOS || TOS
        !           555:        bytes += nlines; /* for the inserted carriage returns */
        !           556: #endif
        !           557:        msg("Wrote \"%s\"  %ld lines, %ld characters", filename, nlines, bytes);
        !           558: 
        !           559:        /* close the file */
        !           560:        close(fd);
        !           561: 
        !           562:        return TRUE;
        !           563: }
        !           564: 
        !           565: 
        !           566: /* This function deletes the temporary file.  If the file has been modified
        !           567:  * and "bang" is FALSE, then it returns FALSE without doing anything; else
        !           568:  * it returns TRUE.
        !           569:  *
        !           570:  * If the "autowrite" option is set, then instead of returning FALSE when
        !           571:  * the file has been modified and "bang" is false, it will call tmpend().
        !           572:  */
        !           573: int tmpabort(bang)
        !           574:        int     bang;
        !           575: {
        !           576:        /* if there is no file, return successfully */
        !           577:        if (tmpfd < 0)
        !           578:        {
        !           579:                return TRUE;
        !           580:        }
        !           581: 
        !           582:        /* see if we must return FALSE -- can't quit */
        !           583:        if (!bang && tstflag(file, MODIFIED))
        !           584:        {
        !           585:                /* if "autowrite" is set, then act like tmpend() */
        !           586:                if (*o_autowrite)
        !           587:                        return tmpend(bang);
        !           588:                else
        !           589:                        return FALSE;
        !           590:        }
        !           591: 
        !           592:        /* delete the tmp file */
        !           593:        cutswitch();
        !           594:        strcpy(prevorig, origname);
        !           595:        prevline = markline(cursor);
        !           596:        *origname = '\0';
        !           597:        origtime = 0L;
        !           598:        blkinit();
        !           599:        nlines = 0;
        !           600:        initflags();
        !           601:        return TRUE;
        !           602: }
        !           603: 
        !           604: /* This function saves the file if it has been modified, and then deletes
        !           605:  * the temporary file. Returns TRUE if successful, or FALSE if the file
        !           606:  * needs to be saved but can't be.  When it returns FALSE, it will not have
        !           607:  * deleted the tmp file, either.
        !           608:  */
        !           609: int tmpend(bang)
        !           610:        int     bang;
        !           611: {
        !           612:        /* save the file if it has been modified */
        !           613:        if (tstflag(file, MODIFIED) && !tmpsave((char *)0, FALSE) && !bang)
        !           614:        {
        !           615:                return FALSE;
        !           616:        }
        !           617: 
        !           618:        /* delete the tmp file */
        !           619:        tmpabort(TRUE);
        !           620: 
        !           621:        return TRUE;
        !           622: }
        !           623: 
        !           624: 
        !           625: /* If the tmp file has been changed, then this function will force those
        !           626:  * changes to be written to the disk, so that the tmp file will survive a
        !           627:  * system crash or power failure.
        !           628:  */
        !           629: #if AMIGA || MSDOS || TOS
        !           630: sync()
        !           631: {
        !           632:        /* MS-DOS and TOS don't flush their buffers until the file is closed,
        !           633:         * so here we close the tmp file and then immediately reopen it.
        !           634:         */
        !           635:        close(tmpfd);
        !           636:        tmpfd = open(tmpname, O_RDWR | O_BINARY);
        !           637:        return 0;
        !           638: }
        !           639: #endif
        !           640: 
        !           641: 
        !           642: /* This function stores the file's name in the second block of the temp file.
        !           643:  * SLEAZE ALERT!  SLEAZE ALERT!  The "tmpblk" buffer is probably being used
        !           644:  * to store the arguments to a command, so we can't use it here.  Instead,
        !           645:  * we'll borrow the buffer that is used for "shift-U".
        !           646:  */
        !           647: int
        !           648: storename(name)
        !           649:        char    *name;  /* the name of the file - normally origname */
        !           650: {
        !           651: #ifndef CRUNCH
        !           652:        int     len;
        !           653:        char    *ptr;
        !           654: #endif
        !           655: 
        !           656:        /* we're going to clobber the U_text buffer, so reset U_line */
        !           657:        U_line = 0L;
        !           658: 
        !           659:        if (!name)
        !           660:        {
        !           661:                strncpy(U_text, "", BLKSIZE);
        !           662:                U_text[1] = 127;
        !           663:        }
        !           664: #ifndef CRUNCH
        !           665:        else if (*name != SLASH)
        !           666:        {
        !           667:                /* get the directory name */
        !           668:                ptr = getcwd(U_text, BLKSIZE);
        !           669:                if (ptr != U_text)
        !           670:                {
        !           671:                        strcpy(U_text, ptr);
        !           672:                }
        !           673: 
        !           674:                /* append a slash to the directory name */
        !           675:                len = strlen(U_text);
        !           676:                U_text[len++] = SLASH;
        !           677: 
        !           678:                /* append the filename, padded with heaps o' NULs */
        !           679:                strncpy(U_text + len, *name ? name : "foo", BLKSIZE - len);
        !           680:        }
        !           681: #endif
        !           682:        else
        !           683:        {
        !           684:                /* copy the filename into U_text */
        !           685:                strncpy(U_text, *name ? name : "foo", BLKSIZE);
        !           686:        }
        !           687: 
        !           688:        if (tmpfd >= 0)
        !           689:        {
        !           690:                /* write the name out to second block of the temp file */
        !           691:                lseek(tmpfd, (long)BLKSIZE, 0);
        !           692:                write(tmpfd, U_text, (unsigned)BLKSIZE);
        !           693:        }
        !           694:        return 0;
        !           695: }
        !           696: 
        !           697: 
        !           698: 
        !           699: /* This function handles deadly signals.  It restores sanity to the terminal
        !           700:  * preserves the current temp file, and deletes any old temp files.
        !           701:  */
        !           702: int deathtrap(sig)
        !           703:        int     sig;    /* the deadly signal that we caught */
        !           704: {
        !           705:        char    *why;
        !           706: 
        !           707:        /* restore the terminal's sanity */
        !           708:        endwin();
        !           709: 
        !           710: #ifdef CRUNCH
        !           711:        why = "-Elvis died";
        !           712: #else
        !           713:        /* give a more specific description of how Elvis died */
        !           714:        switch (sig)
        !           715:        {
        !           716: # ifdef SIGHUP
        !           717:          case SIGHUP:  why = "-the modem lost its carrier";            break;
        !           718: # endif
        !           719: # ifndef DEBUG
        !           720: #  ifdef SIGILL
        !           721:          case SIGILL:  why = "-Elvis hit an illegal instruction";      break;
        !           722: #  endif
        !           723: #  ifdef SIGBUS
        !           724:          case SIGBUS:  why = "-Elvis had a bus error";                 break;
        !           725: #  endif
        !           726: #  ifdef SIGSEGV
        !           727: #   if !TOS
        !           728:          case SIGSEGV: why = "-Elvis had a segmentation violation";    break;
        !           729: #   endif
        !           730: #  endif
        !           731: #  ifdef SIGSYS
        !           732:          case SIGSYS:  why = "-Elvis munged a system call";            break;
        !           733: #  endif
        !           734: # endif /* !DEBUG */
        !           735: # ifdef SIGPIPE
        !           736:          case SIGPIPE: why = "-the pipe reader died";                  break;
        !           737: # endif
        !           738: # ifdef SIGTERM
        !           739:          case SIGTERM: why = "-Elvis was terminated";                  break;
        !           740: # endif
        !           741: # if !MINIX
        !           742: #  ifdef SIGUSR1
        !           743:          case SIGUSR1: why = "-Elvis was killed via SIGUSR1";          break;
        !           744: #  endif
        !           745: #  ifdef SIGUSR2
        !           746:          case SIGUSR2: why = "-Elvis was killed via SIGUSR2";          break;
        !           747: #  endif
        !           748: # endif
        !           749:          default:      why = "-Elvis died";                            break;
        !           750:        }
        !           751: #endif
        !           752: 
        !           753:        /* if we had a temp file going, then preserve it */
        !           754:        if (tmpnum > 0 && tmpfd >= 0)
        !           755:        {
        !           756:                close(tmpfd);
        !           757:                sprintf(tmpblk.c, "%s \"%s\" %s", PRESERVE, why, tmpname);
        !           758:                system(tmpblk.c);
        !           759:        }
        !           760: 
        !           761:        /* delete any old temp files */
        !           762:        cutend();
        !           763: 
        !           764:        /* exit with the proper exit status */
        !           765:        exit(sig);
        !           766: }

unix.superglobalmegacorp.com

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