📄 uusend.c
字号:
/*- * Copyright (c) 1980, 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1980, 1991, 1993\n\ The Regents of the University of California. All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)uusend.c 8.1 (Berkeley) 6/6/93";#endif /* not lint *//* * uusend: primitive operation to allow uucp like copy of binary files * but handle indirection over systems. * * usage: uusend [-r] [-m ooo] localfile sysname1!sysname2!...!destfile * uusend [-r] [-m ooo] - sysname1!sysname2!...!destfile * * Author: Mark Horton, May 1980. * * "-r" switch added. Has same effect as "-r" in uux. 11/82 CCW * * Error recovery (a la uucp) added & ifdefs for ruusend (as in rmail). * Checks for illegal access to /usr/lib/uucp. * February 1983 Christopher Woodbury * Fixed mode set[ug]id loophole. 4/8/83 CCW * * Add '-f' to make uusend syntax more similar to UUCP. "destname" * can now be a directory. June 1983 CCW */#include <sys/types.h>#include <sys/stat.h>#include <stdio.h>#include <pwd.h>/* * define RECOVER to permit requests like 'uusend file sys1!sys2!~uucp' * (abbreviation for 'uusend file sys1!sys2!~uucp/file'). * define DEBUG to keep log of uusend uusage. * define RUUSEND if neighboring sites permit 'ruusend', * which they certainly should to avoid security holes */#define RECOVER/*#define DEBUG "/usr/spool/uucp/uusend.log"/**/FILE *in, *out;FILE *dout;extern FILE *popen();extern char *index(), *strcpy(), *strcat(), *ctime();#ifdef RUUSENDint rsend;#endif RUUSENDint mode = -1; /* mode to chmod new file to */char *nextsys; /* next system in the chain */char dnbuf[200]; /* buffer for result of ~user/file */char cmdbuf[256]; /* buffer to build uux command in */char *rflg = ""; /* default value of rflg ccw -- 1 Nov '82 */struct passwd *user; /* entry in /etc/passwd for ~user */struct passwd *getpwnam();struct stat stbuf;char *excl; /* location of first ! in destname */char *sl; /* location of first / in destname */char *sourcename; /* argv[1] */char *destname; /* argv[2] */char *UULIB = "/usr/lib/uucp"; /* UUCP lib directory */#ifdef RECOVERchar *UUPUB = "/usr/spool/uucppublic/"; /* public UUCP directory */char *filename; /* file name from end of destname */char *getfname(); /* routine to get filename from destname */int fflg;char f[100]; /* name of default output file */#else !RECOVERchar *f = ""; /* so we waste a little space */#endif !RECOVERmain(argc, argv)int argc;char **argv;{ register int c; long count; extern char **environ;#ifdef DEBUG long t; umask(022); dout = fopen(DEBUG, "a"); if (dout == NULL) { printf("Cannot append to %s\n", DEBUG); exit(1); } freopen(DEBUG, "a", stdout); fprintf(dout, "\nuusend run: "); for (c=0; c<argc; c++) fprintf(dout, "%s ", argv[c]); time(&t); fprintf(dout, "%s", ctime(&t));#endif DEBUG#ifdef RUUSEND if(argv[0][0] == 'r') rsend++;#endif RUUSEND while (argc > 1 && argv[1][0] == '-' && argv[1][1]) { switch(argv[1][1]) { case 'm': sscanf(argv[2], "%o", &mode); mode &= 0777; /* fix set[ug]id loophole */ argc--; argv++; break; case 'r': /* -r flag for uux */ rflg = "-r "; break;#ifdef RECOVER case 'f': fflg++; strcpy(f, argv[1]); break;#endif RECOVER default: fprintf(stderr, "Bad flag: %s\n", argv[1]); break; } argc--; argv++; } if (argc != 3) { fprintf(stderr, "Usage: uusend [-m ooo] [-r] -/file sys!sys!..!rfile\n"); exit(1); } sourcename = argv[1]; destname = argv[2]; if (sourcename[0] == '-') in = stdin; else {#ifdef RUUSEND if (rsend) { fprintf(stderr, "illegal input\n"); exit(2); }#endif RUUSEND in = fopen(sourcename, "r"); if (in == NULL) { perror(argv[1]); exit(2); } if (!fflg || f[2] == '\0') { strcpy(f, "-f"); strcat(f, getfname(sourcename)); fflg++; } } excl = index(destname, '!'); if (excl) { /* * destname is on a remote system. */ nextsys = destname; *excl++ = 0; destname = excl; if (mode < 0) { fstat(fileno(in), &stbuf); mode = stbuf.st_mode & 0777; }#ifdef RUUSEND sprintf(cmdbuf,"uux -gn -z %s- \"%s!ruusend %s -m %o - (%s)\"",#else !RUUSEND sprintf(cmdbuf, "uux -gn -z %s- \"%s!uusend %s -m %o - (%s)\"",#endif !RUUSEND rflg, nextsys, f, mode, destname);#ifdef DEBUG fprintf(dout, "remote: nextsys='%s', destname='%s', cmd='%s'\n", nextsys, destname, cmdbuf);#endif DEBUG out = popen(cmdbuf, "w"); } else { /* * destname is local. */ if (destname[0] == '~') {#ifdef DEBUG fprintf(dout, "before ~: '%s'\n", destname);fflush(dout);#endif DEBUG sl = index(destname, '/');#ifdef RECOVER if (sl == NULL && !fflg) { fprintf(stderr, "Illegal ~user\n"); exit(3); } for (sl = destname; *sl != '\0'; sl++) ; /* boy, is this a hack! */#else !RECOVER if (sl == NULL) { fprintf(stderr, "Illegal ~user\n"); exit(3); } *sl++ = 0;#endif !RECOVER user = getpwnam(destname+1); if (user == NULL) { fprintf(stderr, "No such user as %s\n", destname);#ifdef RECOVER if ((filename =getfname(sl)) == NULL && !fflg) exit(4); strcpy(dnbuf, UUPUB); if (fflg) strcat(dnbuf, &f[2]); else strcat(dnbuf, filename); } else { strcpy(dnbuf, user->pw_dir); strcat(dnbuf, "/"); strcat(dnbuf, sl); }#else !RECOVER exit(4); } strcpy(dnbuf, user->pw_dir); strcat(dnbuf, "/"); strcat(dnbuf, sl);#endif !RECOVER destname = dnbuf; }#ifdef RECOVER else destname = strcpy(dnbuf, destname);#endif !RECOVER if(strncmp(UULIB, destname, strlen(UULIB)) == 0) { fprintf(stderr, "illegal file: %s", destname); exit(4); }#ifdef RECOVER if (stat(destname, &stbuf) == 0 && (stbuf.st_mode & S_IFMT) == S_IFDIR && fflg) { strcat(destname, "/"); strcat(destname, &f[2]); }#endif RECOVER out = fopen(destname, "w");#ifdef DEBUG fprintf(dout, "local, file='%s'\n", destname);#endif DEBUG if (out == NULL) { perror(destname);#ifdef RECOVER if (strncmp(destname,UUPUB,strlen(UUPUB)) == 0) exit(5); /* forget it! */ filename = getfname(destname); if (destname == dnbuf) /* cmdbuf is scratch */ filename = strcpy(cmdbuf, filename); destname = strcpy(dnbuf, UUPUB); if (user != NULL) { strcat(destname, user->pw_name); if (stat(destname, &stbuf) == -1) { mkdir(destname, 0777); } strcat(destname, "/"); } if (fflg) strcat(destname, &f[2]); else strcat(destname, filename); if ((out = fopen(destname, "w")) == NULL) exit(5); /* all for naught! */#else !RECOVER exit(5);#endif !RECOVER } if (mode > 0) chmod(destname, mode); /* don't bother to check it */ } /* * Now, in any case, copy from in to out. */ count = 0; while ((c=getc(in)) != EOF) { putc(c, out); count++; }#ifdef DEBUG fprintf(dout, "count %ld bytes\n", count); fclose(dout);#endif DEBUG fclose(in); fclose(out); /* really should pclose in that case */ exit(0);}/* * Return the ptr in sp at which the character c appears; * NULL if not found. Included so I don't have to fight the * index/strchr battle. */#define NULL 0char *index(sp, c)register char *sp, c;{ do { if (*sp == c) return(sp); } while (*sp++); return(NULL);}#ifdef RECOVERchar *getfname(p)register char *p;{ register char *s; s = p; while (*p != '\0') p++; if (p == s) return (NULL); for (;p != s; p--) if (*p == '/') { p++; break; } return (p);}#ifndef BSD4_2makedir(dirname, mode)char *dirname;int mode;{ register int pid; int retcode, status; switch ((pid = fork())) { case -1: /* error */ return (-1); case 0: /* child */ umask(0); execl("/bin/mkdir", "mkdir", dirname, (char *)0); exit(1); /* NOTREACHED */ default: /* parent */ while ((retcode=wait(&status)) != pid && retcode != -1) ; if (retcode == -1) return -1; else { chmod(dirname, mode); return status; } } /* NOTREACHED */}#endif !BSD4_2#endif RECOVER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -