summaryrefslogtreecommitdiff
path: root/src/fileio.c
diff options
context:
space:
mode:
authorjnweiger <jnweiger>2005-12-16 14:34:48 +0000
committerjnweiger <jnweiger>2005-12-16 14:34:48 +0000
commit30f597b9f18d355253b9484bb2f4a1fa5e2e3fb8 (patch)
treeb1a4294758cee774101d18c45d20cf9fa0efec52 /src/fileio.c
parent64434f463765093be5bc53f313848a897ef49c66 (diff)
downloadscreen-30f597b9f18d355253b9484bb2f4a1fa5e2e3fb8.tar.gz
go to ATTIC now.
Diffstat (limited to 'src/fileio.c')
-rw-r--r--src/fileio.c836
1 files changed, 0 insertions, 836 deletions
diff --git a/src/fileio.c b/src/fileio.c
deleted file mode 100644
index ab5e9c7..0000000
--- a/src/fileio.c
+++ /dev/null
@@ -1,836 +0,0 @@
-/* Copyright (c) 1993-2002
- * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- * Copyright (c) 1987 Oliver Laumann
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING); if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- ****************************************************************
- */
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#ifndef SIGINT
-# include <signal.h>
-#endif
-
-#include "config.h"
-#include "screen.h"
-#include "extern.h"
-
-extern struct display *display, *displays;
-extern struct win *fore;
-extern struct layer *flayer;
-extern int real_uid, eff_uid;
-extern int real_gid, eff_gid;
-extern char *extra_incap, *extra_outcap;
-extern char *home, *RcFileName;
-extern char SockPath[], *SockName;
-#ifdef COPY_PASTE
-extern char *BufferFile;
-#endif
-extern int hardcopy_append;
-extern char *hardcopydir;
-
-static char *CatExtra __P((char *, char *));
-static char *findrcfile __P((char *));
-
-
-char *rc_name = "";
-int rc_recursion = 0;
-
-static char *
-CatExtra(str1, str2)
-register char *str1, *str2;
-{
- register char *cp;
- register int len1, len2, add_colon;
-
- len1 = strlen(str1);
- if (len1 == 0)
- return str2;
- add_colon = (str1[len1 - 1] != ':');
- if (str2)
- {
- len2 = strlen(str2);
- if ((cp = realloc(str2, (unsigned) len1 + len2 + add_colon + 1)) == NULL)
- Panic(0, strnomem);
- bcopy(cp, cp + len1 + add_colon, len2 + 1);
- }
- else
- {
- if (len1 == 0)
- return 0;
- if ((cp = malloc((unsigned) len1 + add_colon + 1)) == NULL)
- Panic(0, strnomem);
- cp[len1 + add_colon] = '\0';
- }
- bcopy(str1, cp, len1);
- if (add_colon)
- cp[len1] = ':';
-
- return cp;
-}
-
-static char *
-findrcfile(rcfile)
-char *rcfile;
-{
- char buf[256];
- char *p;
-
- if (rcfile)
- {
- char *rcend = rindex(rc_name, '/');
- if (*rcfile != '/' && rcend && (rcend - rc_name) + strlen(rcfile) + 2 < sizeof(buf))
- {
- strncpy(buf, rc_name, rcend - rc_name + 1);
- strcpy(buf + (rcend - rc_name) + 1, rcfile);
- if (access(buf, R_OK) == 0)
- return SaveStr(buf);
- }
- debug1("findrcfile: you specified '%s'\n", rcfile);
- return SaveStr(rcfile);
- }
- debug("findrcfile: you specified nothing...\n");
- if ((p = getenv("SCREENRC")) != NULL && *p != '\0')
- {
- debug1(" $SCREENRC has: '%s'\n", p);
- return SaveStr(p);
- }
- else
- {
- debug(" ...nothing in $SCREENRC, defaulting $HOME/.screenrc\n");
- if (strlen(home) > sizeof(buf) - 12)
- Panic(0, "Rc: home too large");
- sprintf(buf, "%s/.screenrc", home);
- return SaveStr(buf);
- }
-}
-
-/*
- * this will be called twice:
- * 1) rcfilename = "/etc/screenrc"
- * 2) rcfilename = RcFileName
- */
-void
-StartRc(rcfilename)
-char *rcfilename;
-{
- register int argc, len;
- register char *p, *cp;
- char buf[2048];
- char *args[MAXARGS];
- int argl[MAXARGS];
- FILE *fp;
- char *oldrc_name = rc_name;
-
- /* always fix termcap/info capabilities */
- extra_incap = CatExtra("TF", extra_incap);
-
- /* Special settings for vt100 and others */
- if (display && (!strncmp(D_termname, "vt", 2) || !strncmp(D_termname, "xterm", 5)))
- extra_incap = CatExtra("xn:f0=\033Op:f1=\033Oq:f2=\033Or:f3=\033Os:f4=\033Ot:f5=\033Ou:f6=\033Ov:f7=\033Ow:f8=\033Ox:f9=\033Oy:f.=\033On:f,=\033Ol:fe=\033OM:f+=\033Ok:f-=\033Om:f*=\033Oj:f/=\033Oo:fq=\033OX", extra_incap);
-
- rc_name = findrcfile(rcfilename);
-
- if ((fp = secfopen(rc_name, "r")) == NULL)
- {
- if (!rc_recursion && RcFileName && !strcmp(RcFileName, rc_name))
- {
- /*
- * User explicitly gave us that name,
- * this is the only case, where we get angry, if we can't read
- * the file.
- */
- debug3("StartRc: '%s','%s', '%s'\n", RcFileName, rc_name, rcfilename);
- Panic(0, "Unable to open \"%s\".", rc_name);
- /* NOTREACHED */
- }
- debug1("StartRc: '%s' no good. ignored\n", rc_name);
- Free(rc_name);
- rc_name = oldrc_name;
- return;
- }
- while (fgets(buf, sizeof buf, fp) != NULL)
- {
- if ((p = rindex(buf, '\n')) != NULL)
- *p = '\0';
- if ((argc = Parse(buf, sizeof buf, args, argl)) == 0)
- continue;
- if (strcmp(args[0], "echo") == 0)
- {
- if (!display)
- continue;
- if (argc < 2 || (argc == 3 && strcmp(args[1], "-n")) || argc > 3)
- {
- Msg(0, "%s: 'echo [-n] \"string\"' expected.", rc_name);
- continue;
- }
- AddStr(args[argc - 1]);
- if (argc != 3)
- {
- AddStr("\r\n");
- Flush();
- }
- }
- else if (strcmp(args[0], "sleep") == 0)
- {
- if (!display)
- continue;
- debug("sleeeeeeep\n");
- if (argc != 2)
- {
- Msg(0, "%s: sleep: one numeric argument expected.", rc_name);
- continue;
- }
- DisplaySleep1000(1000 * atoi(args[1]), 1);
- }
-#ifdef TERMINFO
- else if (!strcmp(args[0], "termcapinfo") || !strcmp(args[0], "terminfo"))
-#else
- else if (!strcmp(args[0], "termcapinfo") || !strcmp(args[0], "termcap"))
-#endif
- {
- if (!display)
- continue;
- if (argc < 3 || argc > 4)
- {
- Msg(0, "%s: %s: incorrect number of arguments.", rc_name, args[0]);
- continue;
- }
- for (p = args[1]; p && *p; p = cp)
- {
- if ((cp = index(p, '|')) != 0)
- *cp++ = '\0';
- len = strlen(p);
- if (p[len - 1] == '*')
- {
- if (!(len - 1) || !strncmp(p, D_termname, len - 1))
- break;
- }
- else if (!strcmp(p, D_termname))
- break;
- }
- if (!(p && *p))
- continue;
- extra_incap = CatExtra(args[2], extra_incap);
- if (argc == 4)
- extra_outcap = CatExtra(args[3], extra_outcap);
- }
- else if (!strcmp(args[0], "source"))
- {
- if (rc_recursion <= 10)
- {
- rc_recursion++;
- StartRc(args[1]);
- rc_recursion--;
- }
- }
- }
- fclose(fp);
- Free(rc_name);
- rc_name = oldrc_name;
-}
-
-void
-FinishRc(rcfilename)
-char *rcfilename;
-{
- char buf[2048];
- FILE *fp;
- char *oldrc_name = rc_name;
-
- rc_name = findrcfile(rcfilename);
-
- if ((fp = secfopen(rc_name, "r")) == NULL)
- {
- if (rc_recursion)
- Msg(errno, "%s: source %s", oldrc_name, rc_name);
- else if (RcFileName && !strcmp(RcFileName, rc_name))
- {
- /*
- * User explicitly gave us that name,
- * this is the only case, where we get angry, if we can't read
- * the file.
- */
- debug3("FinishRc:'%s','%s','%s'\n", RcFileName, rc_name, rcfilename);
- Panic(0, "Unable to open \"%s\".", rc_name);
- /* NOTREACHED */
- }
- debug1("FinishRc: '%s' no good. ignored\n", rc_name);
- Free(rc_name);
- rc_name = oldrc_name;
- return;
- }
-
- debug("finishrc is going...\n");
- while (fgets(buf, sizeof buf, fp) != NULL)
- RcLine(buf, sizeof buf);
- (void) fclose(fp);
- Free(rc_name);
- rc_name = oldrc_name;
-}
-
-void
-do_source(rcfilename)
-char *rcfilename;
-{
- if (rc_recursion > 10)
- {
- Msg(0, "%s: source: recursion limit reached", rc_name);
- return;
- }
- rc_recursion++;
- FinishRc(rcfilename);
- rc_recursion--;
-}
-
-
-/*
- * Running a Command Line in the environment determined by the display.
- * The fore window is taken from the display as well as the user.
- * This is bad when we run detached.
- */
-void
-RcLine(ubuf, ubufl)
-char *ubuf;
-int ubufl;
-{
- char *args[MAXARGS];
- int argl[MAXARGS];
-#ifdef MULTIUSER
- extern struct acluser *EffectiveAclUser; /* acl.c */
- extern struct acluser *users; /* acl.c */
-#endif
-
- if (display)
- {
- fore = D_fore;
- flayer = D_forecv->c_layer;
- }
- else
- flayer = fore ? fore->w_savelayer : 0;
- if (Parse(ubuf, ubufl, args, argl) <= 0)
- return;
-#ifdef MULTIUSER
- if (!display)
- {
- /* the session owner does it, when there is no display here */
- EffectiveAclUser = users;
- debug("RcLine: WARNING, no display no user! Session owner executes command\n");
- }
-#endif
- DoCommand(args, argl);
-#ifdef MULTIUSER
- EffectiveAclUser = 0;
-#endif
-}
-
-/*
- * needs display for copybuffer access and termcap dumping
- */
-void
-WriteFile(user, fn, dump)
-struct acluser *user;
-char *fn;
-int dump;
-{
- /* dump==0: create .termcap,
- * dump==1: hardcopy,
- * #ifdef COPY_PASTE
- * dump==2: BUFFERFILE
- * #endif COPY_PASTE
- * dump==1: scrollback,
- */
- register int i, j, k;
- register char *p;
- register FILE *f;
- char fnbuf[1024];
- char *mode = "w";
-#ifdef COPY_PASTE
- int public = 0;
-# ifdef _MODE_T
- mode_t old_umask;
-# else
- int old_umask;
-# endif
-# ifdef HAVE_LSTAT
- struct stat stb, stb2;
- int fd, exists = 0;
-# endif
-#endif
-
- switch (dump)
- {
- case DUMP_TERMCAP:
- if (fn == 0)
- {
- i = SockName - SockPath;
- if (i > (int)sizeof(fnbuf) - 9)
- i = 0;
- strncpy(fnbuf, SockPath, i);
- strcpy(fnbuf + i, ".termcap");
- fn = fnbuf;
- }
- break;
- case DUMP_HARDCOPY:
- case DUMP_SCROLLBACK:
- if (fn == 0)
- {
- if (fore == 0)
- return;
- if (hardcopydir && *hardcopydir && strlen(hardcopydir) < sizeof(fnbuf) - 21)
- sprintf(fnbuf, "%s/hardcopy.%d", hardcopydir, fore->w_number);
- else
- sprintf(fnbuf, "hardcopy.%d", fore->w_number);
- fn = fnbuf;
- }
- if (hardcopy_append && !access(fn, W_OK))
- mode = "a";
- break;
-#ifdef COPY_PASTE
- case DUMP_EXCHANGE:
- if (fn == 0)
- {
- strncpy(fnbuf, BufferFile, sizeof(fnbuf) - 1);
- fnbuf[sizeof(fnbuf) - 1] = 0;
- fn = fnbuf;
- }
- public = !strcmp(fn, DEFAULT_BUFFERFILE);
-# ifdef HAVE_LSTAT
- exists = !lstat(fn, &stb);
- if (public && exists && (S_ISLNK(stb.st_mode) || stb.st_nlink > 1))
- {
- Msg(0, "No write to links, please.");
- return;
- }
-# endif
- break;
-#endif
- }
-
- debug2("WriteFile(%d) %s\n", dump, fn);
- if (UserContext() > 0)
- {
- debug("Writefile: usercontext\n");
-#ifdef COPY_PASTE
- if (dump == DUMP_EXCHANGE && public)
- {
- old_umask = umask(0);
-# ifdef HAVE_LSTAT
- if (exists)
- {
- if ((fd = open(fn, O_WRONLY, 0666)) >= 0)
- {
- if (fstat(fd, &stb2) == 0 && stb.st_dev == stb2.st_dev && stb.st_ino == stb2.st_ino)
- ftruncate(fd, 0);
- else
- {
- close(fd);
- fd = -1;
- }
- }
- }
- else
- fd = open(fn, O_WRONLY|O_CREAT|O_EXCL, 0666);
- f = fd >= 0 ? fdopen(fd, mode) : 0;
-# else
- f = fopen(fn, mode);
-# endif
- umask(old_umask);
- }
- else
-#endif /* COPY_PASTE */
- f = fopen(fn, mode);
- if (f == NULL)
- {
- debug2("WriteFile: fopen(%s,\"%s\") failed\n", fn, mode);
- UserReturn(0);
- }
- else
- {
- switch (dump)
- {
- case DUMP_HARDCOPY:
- case DUMP_SCROLLBACK:
- if (!fore)
- break;
- if (*mode == 'a')
- {
- putc('>', f);
- for (j = fore->w_width - 2; j > 0; j--)
- putc('=', f);
- fputs("<\n", f);
- }
- if (dump == DUMP_SCROLLBACK)
- {
- for (i = 0; i < fore->w_histheight; i++)
- {
- p = (char *)(WIN(i)->image);
- for (k = fore->w_width - 1; k >= 0 && p[k] == ' '; k--)
- ;
- for (j = 0; j <= k; j++)
- putc(p[j], f);
- putc('\n', f);
- }
- }
- for (i = 0; i < fore->w_height; i++)
- {
- p = (char *)fore->w_mlines[i].image;
- for (k = fore->w_width - 1; k >= 0 && p[k] == ' '; k--)
- ;
- for (j = 0; j <= k; j++)
- putc(p[j], f);
- putc('\n', f);
- }
- break;
- case DUMP_TERMCAP:
- if ((p = index(MakeTermcap(fore->w_aflag), '=')) != NULL)
- {
- fputs(++p, f);
- putc('\n', f);
- }
- break;
-#ifdef COPY_PASTE
- case DUMP_EXCHANGE:
- p = user->u_plop.buf;
- for (i = user->u_plop.len; i-- > 0; p++)
- if (*p == '\r' && (i == 0 || p[1] != '\n'))
- putc('\n', f);
- else
- putc(*p, f);
- break;
-#endif
- }
- (void) fclose(f);
- UserReturn(1);
- }
- }
- if (UserStatus() <= 0)
- Msg(0, "Cannot open \"%s\"", fn);
- else if (display && !*rc_name)
- {
- switch (dump)
- {
- case DUMP_TERMCAP:
- Msg(0, "Termcap entry written to \"%s\".", fn);
- break;
- case DUMP_HARDCOPY:
- case DUMP_SCROLLBACK:
- Msg(0, "Screen image %s to \"%s\".",
- (*mode == 'a') ? "appended" : "written", fn);
- break;
-#ifdef COPY_PASTE
- case DUMP_EXCHANGE:
- Msg(0, "Copybuffer written to \"%s\".", fn);
-#endif
- }
- }
-}
-
-#ifdef COPY_PASTE
-
-/*
- * returns an allocated buffer which holds a copy of the file named fn.
- * lenp (if nonzero) points to a location, where the buffer size should be
- * stored.
- */
-char *
-ReadFile(fn, lenp)
-char *fn;
-int *lenp;
-{
- int i, l, size;
- char c, *bp, *buf;
- struct stat stb;
-
- ASSERT(lenp);
- debug1("ReadFile(%s)\n", fn);
- if ((i = secopen(fn, O_RDONLY, 0)) < 0)
- {
- Msg(errno, "no %s -- no slurp", fn);
- return NULL;
- }
- if (fstat(i, &stb))
- {
- Msg(errno, "no good %s -- no slurp", fn);
- close(i);
- return NULL;
- }
- size = stb.st_size;
- if ((buf = malloc(size)) == NULL)
- {
- close(i);
- Msg(0, strnomem);
- return NULL;
- }
- errno = 0;
- if ((l = read(i, buf, size)) != size)
- {
- if (l < 0)
- l = 0;
- Msg(errno, "Got only %d bytes from %s", l, fn);
- close(i);
- }
- else
- {
- if (read(i, &c, 1) > 0)
- Msg(0, "Slurped only %d characters (of %d) into buffer - try again",
- l, size);
- else
- Msg(0, "Slurped %d characters into buffer", l);
- }
- close(i);
- *lenp = l;
- for (bp = buf; l-- > 0; bp++)
- if (*bp == '\n' && (bp == buf || bp[-1] != '\r'))
- *bp = '\r';
- return buf;
-}
-
-void
-KillBuffers()
-{
- if (UserContext() > 0)
- UserReturn(unlink(BufferFile) ? errno : 0);
- errno = UserStatus();
- Msg(errno, "%s %sremoved", BufferFile, errno ? "not " : "");
-}
-#endif /* COPY_PASTE */
-
-
-/*
- * (Almost) secure open and fopen...
- */
-
-FILE *
-secfopen(name, mode)
-char *name;
-char *mode;
-{
- FILE *fi;
-#ifndef USE_SETEUID
- int flags, fd;
-#endif
-
- debug2("secfopen(%s, %s)\n", name, mode);
-#ifdef USE_SETEUID
- xseteuid(real_uid);
- xsetegid(real_gid);
- fi = fopen(name, mode);
- xseteuid(eff_uid);
- xsetegid(eff_gid);
- return fi;
-#else
- if (eff_uid == real_uid)
- return fopen(name, mode);
- if (mode[0] && mode[1] == '+')
- flags = O_RDWR;
- else
- flags = (mode[0] == 'r') ? O_RDONLY : O_WRONLY;
- if (mode[0] == 'w')
- flags |= O_CREAT | O_TRUNC;
- else if (mode[0] == 'a')
- flags |= O_CREAT | O_APPEND;
- else if (mode[0] != 'r')
- {
- errno = EINVAL;
- return 0;
- }
- if ((fd = secopen(name, flags, 0666)) < 0)
- return 0;
- if ((fi = fdopen(fd, mode)) == 0)
- {
- close(fd);
- return 0;
- }
- return fi;
-#endif
-}
-
-
-int
-secopen(name, flags, mode)
-char *name;
-int flags;
-int mode;
-{
- int fd;
-#ifndef USE_SETEUID
- int q;
- struct stat stb;
-#endif
-
- debug3("secopen(%s, 0x%x, 0%03o)\n", name, flags, mode);
-#ifdef USE_SETEUID
- xseteuid(real_uid);
- xsetegid(real_gid);
- fd = open(name, flags, mode);
- xseteuid(eff_uid);
- xsetegid(eff_gid);
- return fd;
-#else
- if (eff_uid == real_uid)
- return open(name, flags, mode);
- /* Truncation/creation is done in UserContext */
- if ((flags & O_TRUNC) || ((flags & O_CREAT) && access(name, F_OK)))
- {
- if (UserContext() > 0)
- {
- if ((fd = open(name, flags, mode)) >= 0)
- {
- close(fd);
- UserReturn(0);
- }
- if (errno == 0)
- errno = EACCES;
- UserReturn(errno);
- }
- if ((q = UserStatus()))
- {
- if (q > 0)
- errno = q;
- return -1;
- }
- }
- if (access(name, F_OK))
- return -1;
- if ((fd = open(name, flags & ~(O_TRUNC | O_CREAT), 0)) < 0)
- return -1;
- debug("open successful\n");
- if (fstat(fd, &stb))
- {
- close(fd);
- return -1;
- }
- debug("fstat successful\n");
- if (stb.st_uid != real_uid)
- {
- switch (flags & (O_RDONLY | O_WRONLY | O_RDWR))
- {
- case O_RDONLY:
- q = 0004;
- break;
- case O_WRONLY:
- q = 0002;
- break;
- default:
- q = 0006;
- break;
- }
- if ((stb.st_mode & q) != q)
- {
- debug1("secopen: permission denied (%03o)\n", stb.st_mode & 07777);
- close(fd);
- errno = EACCES;
- return -1;
- }
- }
- debug1("secopen ok - returning %d\n", fd);
- return fd;
-#endif
-}
-
-
-int
-printpipe(p, cmd)
-struct win *p;
-char *cmd;
-{
- int pi[2];
- if (pipe(pi))
- {
- WMsg(p, errno, "printing pipe");
- return -1;
- }
- switch (fork())
- {
- case -1:
- WMsg(p, errno, "printing fork");
- return -1;
- case 0:
- display = p->w_pdisplay;
- displays = 0;
-#ifdef DEBUG
- if (dfp && dfp != stderr)
- fclose(dfp);
-#endif
- close(0);
- dup(pi[0]);
- closeallfiles(0);
- if (setgid(real_gid) || setuid(real_uid))
- Panic(errno, "printpipe setuid");
-#ifdef SIGPIPE
- signal(SIGPIPE, SIG_DFL);
-#endif
- execl("/bin/sh", "sh", "-c", cmd, 0);
- Panic(errno, "/bin/sh");
- default:
- break;
- }
- close(pi[0]);
- return pi[1];
-}
-
-int
-readpipe(cmdv)
-char **cmdv;
-{
- int pi[2];
-
- if (pipe(pi))
- {
- Msg(errno, "pipe");
- return -1;
- }
- switch (fork())
- {
- case -1:
- Msg(errno, "fork");
- return -1;
- case 0:
- displays = 0;
-#ifdef DEBUG
- if (dfp && dfp != stderr)
- fclose(dfp);
-#endif
- close(1);
- if (dup(pi[1]) != 1)
- {
- close(pi[1]);
- Panic(0, "dup");
- }
- closeallfiles(1);
- if (setgid(real_gid) || setuid(real_uid))
- {
- close(1);
- Panic(errno, "setuid/setgid");
- }
-#ifdef SIGPIPE
- signal(SIGPIPE, SIG_DFL);
-#endif
- execvp(*cmdv, cmdv);
- close(1);
- Panic(errno, *cmdv);
- default:
- break;
- }
- close(pi[1]);
- return pi[0];
-}