Home | History | Annotate | Download | only in bnu
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * 	Copyright (c) 1999 by Sun Microsystems, Inc.
     24  * 	All rights reserved.
     25  */
     26 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     27 /*	  All Rights Reserved  	*/
     28 
     29 
     30 #ident	"%Z%%M%	%I%	%E% SMI"	/* from SVR4 bnu:cpmv.c	2.13 */
     31 
     32 #include "uucp.h"
     33 
     34 /*
     35  * copy f1 to f2 locally
     36  *	f1	-> source file name
     37  *	f2	-> destination file name
     38  * return:
     39  *	0	-> ok
     40  *	FAIL	-> failed
     41  */
     42 
     43 static int
     44 xcp(f1, f2)
     45 char *f1, *f2;
     46 {
     47 	register int	fd1, fd2;
     48 	register int	nr, nw;
     49 	char buf[BUFSIZ];
     50 	char *temp_p, temp[MAXFULLNAME];
     51 
     52 	if ((fd1 = open(f1, O_RDONLY)) == -1)
     53 		return (FAIL);
     54 
     55 	if (DIRECTORY(f2)) {
     56 		(void) strcat(f2, "/");
     57 		(void) strcat(f2, BASENAME(f1, '/'));
     58 	}
     59 	DEBUG(4, "file name is %s\n", f2);
     60 
     61 	(void) strcpy(temp, f2);
     62 	if ((temp_p = strrchr(temp, '/')) == NULL)
     63 	    temp_p = temp;
     64 	else
     65 	    temp_p++;
     66 	(void) strcpy(temp_p, ".TM.XXXXXX");
     67 	temp_p = temp;
     68 	DEBUG(4, "temp name is %s\n", temp_p);
     69 
     70 	if ((fd2 = mkstemp(temp_p)) == -1) {
     71 		/* open of temp may fail if called from uidxcp() */
     72 		/* in this case, try f2 since it is pre-created */
     73 		temp_p = f2;
     74 		if ((fd2 = open(temp_p, O_CREAT | O_TRUNC | O_WRONLY,
     75 		    PUB_FILEMODE)) == -1) {
     76 			DEBUG(5, "open of file returned errno %d\n", errno);
     77 			(void) close(fd1);
     78 			return (FAIL);
     79 		}
     80 		DEBUG(4, "using file name directly.%s\n", "");
     81 	}
     82 	(void) chmod(temp_p, PUB_FILEMODE);
     83 
     84 	/*	copy, looking for read or write failures */
     85 	while ((nr = read(fd1, buf, sizeof (buf))) > 0 &&
     86 		(nw = write(fd2, buf, nr)) == nr)
     87 		;
     88 
     89 	close(fd1);
     90 	close(fd2);
     91 
     92 	if (nr != 0 || nw == -1) {
     93 		(void) unlink(temp_p);
     94 		return (FAIL);
     95 	}
     96 	if (temp_p != f2) {
     97 	    if (rename(temp_p, f2) != 0) {
     98 		DEBUG(5, "rename failed: errno %d\n", errno);
     99 		(void) unlink(temp_p);
    100 		return (FAIL);
    101 	    }
    102 	}
    103 	return (0);
    104 }
    105 
    106 
    107 /*
    108  * move f1 to f2 locally
    109  * returns:
    110  *	0	-> ok
    111  *	FAIL	-> failed
    112  */
    113 
    114 int
    115 xmv(f1, f2)
    116 register char *f1, *f2;
    117 {
    118 	register int do_unlink, ret;
    119 	struct stat sbuf;
    120 
    121 	if (stat(f2, &sbuf) == 0)
    122 		do_unlink = ((sbuf.st_mode & S_IFMT) == S_IFREG);
    123 	else
    124 		do_unlink = 1;
    125 
    126 	if (do_unlink)
    127 		(void) unlink(f2);	/* i'm convinced this is the right */
    128 					/* thing to do */
    129 	if ((ret = link(f1, f2)) < 0) {
    130 	    /* copy file */
    131 	    ret = xcp(f1, f2);
    132 	}
    133 
    134 	if (ret == 0)
    135 	    (void) unlink(f1);
    136 	return (ret);
    137 }
    138 
    139 /*
    140  * toCorrupt - move file to CORRUPTDIR
    141  * return - none
    142  */
    143 
    144 void
    145 toCorrupt(file)
    146 char *file;
    147 {
    148 	char corrupt[MAXFULLNAME];
    149 
    150 	(void) sprintf(corrupt, "%s/%s", CORRUPTDIR, BASENAME(file, '/'));
    151 	(void) link(file, corrupt);
    152 	ASSERT(unlink(file) == 0, Ct_UNLINK, file, errno);
    153 }
    154 
    155 /*
    156  * append f1 to f2
    157  *	f1	-> source FILE pointer
    158  *	f2	-> destination FILE pointer
    159  * return:
    160  *	SUCCESS	-> ok
    161  *	FAIL	-> failed
    162  *
    163  * to avoid confusing mail, turn lines with just "." into "..".
    164  */
    165 int
    166 xfappend(fp1, fp2)
    167 register FILE	*fp1, *fp2;
    168 {
    169 	char	buf[BUFSIZ];
    170 
    171 	while (fgets(buf, sizeof (buf), fp1) != NULL) {
    172 		if (buf[0] == '.' && buf[1] == '\n')
    173 			strcpy(buf, "..\n");
    174 		fputs(buf, fp2);
    175 	}
    176 
    177 	return (ferror(fp1) || ferror(fp2) ? FAIL : SUCCESS);
    178 }
    179 
    180 
    181 /*
    182  * copy f1 to f2 locally under uid of uid argument
    183  *	f1	-> source file name
    184  *	f2	-> destination file name
    185  *	Uid and Euid are global
    186  * return:
    187  *	0	-> ok
    188  *	FAIL	-> failed
    189  * NOTES:
    190  *  for V7 systems, flip-flop between real and effective uid is
    191  *  not allowed, so fork must be done.  This code will not
    192  *  work correctly when realuid is root on System 5 because of
    193  *  a bug in setuid.
    194  */
    195 
    196 int
    197 uidxcp(f1, f2)
    198 char *f1, *f2;
    199 {
    200 	int status;
    201 	char full[MAXFULLNAME];
    202 
    203 	(void) strcpy(full, f2);
    204 	if (DIRECTORY(f2)) {
    205 	    (void) strcat(full, "/");
    206 	    (void) strcat(full, BASENAME(f1, '/'));
    207 	}
    208 
    209 	/* create full owned by uucp */
    210 	(void) close(creat(full, PUB_FILEMODE));
    211 	(void) chmod(full, PUB_FILEMODE);
    212 
    213 	/* do file copy as read uid */
    214 #ifndef V7
    215 	(void) setuid(Uid);
    216 	status = xcp(f1, full);
    217 	(void) setuid(Euid);
    218 	return (status);
    219 
    220 #else /* V7 */
    221 
    222 	if (vfork() == 0) {
    223 	    setuid(Uid);
    224 	    _exit(xcp(f1, full));
    225 	}
    226 	wait(&status);
    227 	return (status);
    228 #endif
    229 }
    230 
    231 /*
    232  * put file in public place
    233  * if successful, filename is modified
    234  * returns:
    235  *	0	-> success
    236  *	FAIL	-> failure
    237  */
    238 int
    239 putinpub(file, tmp, user)
    240 char *file, *user, *tmp;
    241 {
    242 	int status;
    243 	char fullname[MAXFULLNAME];
    244 
    245 	(void) sprintf(fullname, "%s/%s/", Pubdir, user);
    246 	if (mkdirs(fullname, PUBMASK) != 0) {
    247 		/* cannot make directories */
    248 		return (FAIL);
    249 	}
    250 	(void) strcat(fullname, BASENAME(file, '/'));
    251 	status = xmv(tmp, fullname);
    252 	if (status == 0) {
    253 		(void) strcpy(file, fullname);
    254 		(void) chmod(fullname, PUB_FILEMODE);
    255 	}
    256 	return (status);
    257 }
    258