added PDX constant
[unix-history] / usr / src / usr.bin / ex / ex_io.c
index 52db2a6..4cc4e30 100644 (file)
@@ -1,5 +1,5 @@
-/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_io.c     4.2 %G%";
+/* Copyright (c) 1981 Regents of the University of California */
+static char *sccsid = "@(#)ex_io.c     7.4     %G%";
 #include "ex.h"
 #include "ex_argv.h"
 #include "ex_temp.h"
 #include "ex.h"
 #include "ex_argv.h"
 #include "ex_temp.h"
@@ -277,10 +277,10 @@ gscan()
 /*
  * Parse one filename into file.
  */
 /*
  * Parse one filename into file.
  */
+struct glob G;
 getone()
 {
        register char *str;
 getone()
 {
        register char *str;
-       struct glob G;
 
        if (getargs() == 0)
                error("Missing filename");
 
        if (getargs() == 0)
                error("Missing filename");
@@ -304,11 +304,24 @@ rop(c)
        register int i;
        struct stat stbuf;
        short magic;
        register int i;
        struct stat stbuf;
        short magic;
+       static int ovro;        /* old value(READONLY) */
+       static int denied;      /* 1 if READONLY was set due to file permissions */
 
        io = open(file, 0);
        if (io < 0) {
 
        io = open(file, 0);
        if (io < 0) {
-               if (c == 'e' && errno == ENOENT)
+               if (c == 'e' && errno == ENOENT) {
                        edited++;
                        edited++;
+                       /*
+                        * If the user just did "ex foo" he is probably
+                        * creating a new file.  Don't be an error, since
+                        * this is ugly, and it screws up the + option.
+                        */
+                       if (!seenprompt) {
+                               printf(" [New file]");
+                               noonl();
+                               return;
+                       }
+               }
                syserror();
        }
        if (fstat(io, &stbuf))
                syserror();
        }
        if (fstat(io, &stbuf))
@@ -329,30 +342,64 @@ rop(c)
                error(" Directory");
 
        case S_IFREG:
                error(" Directory");
 
        case S_IFREG:
+#ifdef CRYPT
                if (xflag)
                        break;
                if (xflag)
                        break;
+#endif
                i = read(io, (char *) &magic, sizeof(magic));
                lseek(io, 0l, 0);
                if (i != sizeof(magic))
                        break;
                switch (magic) {
 
                i = read(io, (char *) &magic, sizeof(magic));
                lseek(io, 0l, 0);
                if (i != sizeof(magic))
                        break;
                switch (magic) {
 
-               case 0405:
-               case 0407:
-               case 0410:
-               case 0411:
+               case 0405:      /* data overlay on exec */
+               case 0407:      /* unshared */
+               case 0410:      /* shared text */
+               case 0411:      /* separate I/D */
+               case 0413:      /* VM/Unix demand paged */
+               case 0430:      /* PDP-11 Overlay shared */
+               case 0431:      /* PDP-11 Overlay sep I/D */
                        error(" Executable");
 
                        error(" Executable");
 
+               /*
+                * We do not forbid the editing of portable archives
+                * because it is reasonable to edit them, especially
+                * if they are archives of text files.  This is
+                * especially useful if you archive source files together
+                * and copy them to another system with ~%take, since
+                * the files sometimes show up munged and must be fixed.
+                */
                case 0177545:
                case 0177555:
                        error(" Archive");
 
                default:
                case 0177545:
                case 0177555:
                        error(" Archive");
 
                default:
+#ifdef mbb
+                       /* C/70 has a 10 bit byte */
+                       if (magic & 03401600)
+#else
+                       /* Everybody else has an 8 bit byte */
                        if (magic & 0100200)
                        if (magic & 0100200)
+#endif
                                error(" Non-ascii file");
                        break;
                }
        }
                                error(" Non-ascii file");
                        break;
                }
        }
+       if (c != 'r') {
+               if (value(READONLY) && denied) {
+                       value(READONLY) = ovro;
+                       denied = 0;
+               }
+               if ((stbuf.st_mode & 0222) == 0 || access(file, 2) < 0) {
+                       ovro = value(READONLY);
+                       denied = 1;
+                       value(READONLY) = 1;
+               }
+       }
+       if (value(READONLY)) {
+               printf(" [Read only]");
+               flush();
+       }
        if (c == 'r')
                setdot();
        else
        if (c == 'r')
                setdot();
        else
@@ -365,10 +412,19 @@ rop(c)
 
 rop2()
 {
 
 rop2()
 {
+       line *first, *last, *a;
 
        deletenone();
        clrstats();
 
        deletenone();
        clrstats();
+       first = addr2 + 1;
        ignore(append(getfile, addr2));
        ignore(append(getfile, addr2));
+       last = dot;
+       for (a=first; a<=last; a++) {
+               if (a==first+5 && last-first > 10)
+                       a = last - 4;
+               getline(*a);
+               checkmodeline(linebuf);
+       }
 }
 
 rop3(c)
 }
 
 rop3(c)
@@ -515,6 +571,7 @@ cre:
 #endif
                if (io < 0)
                        syserror();
 #endif
                if (io < 0)
                        syserror();
+               writing = 1;
                if (hush == 0)
                        if (nonexist)
                                printf(" [New file]");
                if (hush == 0)
                        if (nonexist)
                                printf(" [New file]");
@@ -532,7 +589,7 @@ cre:
                lseek(io, 0l, 2);
                break;
        }
                lseek(io, 0l, 2);
                break;
        }
-       putfile();
+       putfile(0);
        ignore(iostats());
        if (c != 2 && addr1 == one && addr2 == dol) {
                if (eq(file, savedfile))
        ignore(iostats());
        if (c != 2 && addr1 == one && addr2 == dol) {
                if (eq(file, savedfile))
@@ -543,6 +600,7 @@ cre:
                addr1 = saddr1;
                addr2 = saddr2;
        }
                addr1 = saddr1;
                addr2 = saddr2;
        }
+       writing = 0;
 }
 
 /*
 }
 
 /*
@@ -562,7 +620,7 @@ edfile()
 /*
  * Extract the next line from the io stream.
  */
 /*
  * Extract the next line from the io stream.
  */
-static char *nextip;
+char *nextip;
 
 getfile()
 {
 
 getfile()
 {
@@ -582,6 +640,7 @@ getfile()
                                }
                                return (EOF);
                        }
                                }
                                return (EOF);
                        }
+#ifdef CRYPT
                        fp = genbuf;
                        while(fp < &genbuf[ninbuf]) {
                                if (*fp++ & 0200) {
                        fp = genbuf;
                        while(fp < &genbuf[ninbuf]) {
                                if (*fp++ & 0200) {
@@ -591,6 +650,7 @@ cntch);
                                        break;
                                }
                        }
                                        break;
                                }
                        }
+#endif
                        fp = genbuf;
                        cntch += ninbuf+1;
                }
                        fp = genbuf;
                        cntch += ninbuf+1;
                }
@@ -619,7 +679,8 @@ cntch);
 /*
  * Write a range onto the io stream.
  */
 /*
  * Write a range onto the io stream.
  */
-putfile()
+putfile(isfilter)
+int isfilter;
 {
        line *a1;
        register char *fp, *lp;
 {
        line *a1;
        register char *fp, *lp;
@@ -638,8 +699,10 @@ putfile()
                for (;;) {
                        if (--nib < 0) {
                                nib = fp - genbuf;
                for (;;) {
                        if (--nib < 0) {
                                nib = fp - genbuf;
-                               if(kflag)
+#ifdef CRYPT
+                               if(kflag && !isfilter)
                                         crblock(perm, genbuf, nib, cntch);
                                         crblock(perm, genbuf, nib, cntch);
+#endif
                                if (write(io, genbuf, nib) != nib) {
                                        wrerror();
                                }
                                if (write(io, genbuf, nib) != nib) {
                                        wrerror();
                                }
@@ -654,8 +717,10 @@ putfile()
                }
        } while (a1 <= addr2);
        nib = fp - genbuf;
                }
        } while (a1 <= addr2);
        nib = fp - genbuf;
-       if(kflag)
+#ifdef CRYPT
+       if(kflag && !isfilter)
                crblock(perm, genbuf, nib, cntch);
                crblock(perm, genbuf, nib, cntch);
+#endif
        if (write(io, genbuf, nib) != nib) {
                wrerror();
        }
        if (write(io, genbuf, nib) != nib) {
                wrerror();
        }
@@ -688,9 +753,14 @@ source(fil, okfail)
 {
        jmp_buf osetexit;
        register int saveinp, ointty, oerrno;
 {
        jmp_buf osetexit;
        register int saveinp, ointty, oerrno;
+       char *saveglobp;
+       short savepeekc;
 
        signal(SIGINT, SIG_IGN);
        saveinp = dup(0);
 
        signal(SIGINT, SIG_IGN);
        saveinp = dup(0);
+       savepeekc = peekc;
+       saveglobp = globp;
+       peekc = 0; globp = 0;
        if (saveinp < 0)
                error("Too many nested sources");
        if (slevel <= 0)
        if (saveinp < 0)
                error("Too many nested sources");
        if (slevel <= 0)
@@ -728,6 +798,8 @@ source(fil, okfail)
        close(0);
        dup(saveinp);
        close(saveinp);
        close(0);
        dup(saveinp);
        close(saveinp);
+       globp = saveglobp;
+       peekc = savepeekc;
        slevel--;
        resexit(osetexit);
 }
        slevel--;
        resexit(osetexit);
 }
@@ -775,3 +847,31 @@ iostats()
        }
        return (cntnull != 0 || cntodd != 0);
 }
        }
        return (cntnull != 0 || cntodd != 0);
 }
+
+#if USG | USG3TTY
+/* It's so wonderful how we all speak the same language... */
+# define index strchr
+# define rindex strrchr
+#endif
+
+checkmodeline(line)
+char *line;
+{
+       char *beg, *end;
+       char cmdbuf[1024];
+       char *index(), *rindex();
+
+       beg = index(line, ':');
+       if (beg == NULL)
+               return;
+       if (beg[-2] != 'e' && beg[-2] != 'v') return;
+       if (beg[-1] != 'x' && beg[-1] != 'i') return;
+
+       strncpy(cmdbuf, beg+1, sizeof cmdbuf);
+       end = rindex(cmdbuf, ':');
+       if (end == NULL)
+               return;
+       *end = 0;
+       globp = cmdbuf;
+       commands(1, 1);
+}