util.c revision 50471
1239313Sdim/*- 2239313Sdim * Copyright (c) 1992, 1993 3239313Sdim * The Regents of the University of California. All rights reserved. 4239313Sdim * 5239313Sdim * Redistribution and use in source and binary forms, with or without 6239313Sdim * modification, are permitted provided that the following conditions 7239313Sdim * are met: 8239313Sdim * 1. Redistributions of source code must retain the above copyright 9239313Sdim * notice, this list of conditions and the following disclaimer. 10239313Sdim * 2. Redistributions in binary form must reproduce the above copyright 11239313Sdim * notice, this list of conditions and the following disclaimer in the 12239313Sdim * documentation and/or other materials provided with the distribution. 13239313Sdim * 3. All advertising materials mentioning features or use of this software 14239313Sdim * must display the following acknowledgement: 15239313Sdim * This product includes software developed by the University of 16239313Sdim * California, Berkeley and its contributors. 17239313Sdim * 4. Neither the name of the University nor the names of its contributors 18239313Sdim * may be used to endorse or promote products derived from this software 19239313Sdim * without specific prior written permission. 20239313Sdim * 21239313Sdim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22245431Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23252723Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24239313Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25239313Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26239313Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27239313Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28239313Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29239313Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30239313Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31239313Sdim * SUCH DAMAGE. 32239313Sdim */ 33239313Sdim 34239313Sdim#ifndef lint 35239313Sdim#if 0 36239313Sdimstatic char sccsid[] = "@(#)util.c 8.2 (Berkeley) 4/2/94"; 37239313Sdim#endif 38239313Sdimstatic const char rcsid[] = 39239313Sdim "$FreeBSD: head/bin/rcp/util.c 50471 1999-08-27 23:15:48Z peter $"; 40239313Sdim#endif /* not lint */ 41239313Sdim 42239313Sdim#include <sys/param.h> 43239313Sdim#include <sys/stat.h> 44239313Sdim#include <sys/wait.h> 45239313Sdim 46239313Sdim#include <ctype.h> 47239313Sdim#include <err.h> 48239313Sdim#include <errno.h> 49239313Sdim#include <paths.h> 50239313Sdim#include <signal.h> 51239313Sdim#include <stdio.h> 52239313Sdim#include <stdlib.h> 53239313Sdim#include <string.h> 54239313Sdim#include <unistd.h> 55239313Sdim 56239313Sdim#include "extern.h" 57239313Sdim 58239313Sdimchar * 59239313Sdimcolon(cp) 60239313Sdim char *cp; 61239313Sdim{ 62239313Sdim if (*cp == ':') /* Leading colon is part of file name. */ 63239313Sdim return (0); 64239313Sdim 65239313Sdim for (; *cp; ++cp) { 66239313Sdim if (*cp == ':') 67239313Sdim return (cp); 68239313Sdim if (*cp == '/') 69239313Sdim return (0); 70239313Sdim } 71239313Sdim return (0); 72245431Sdim} 73239313Sdim 74245431Sdimvoid 75245431Sdimverifydir(cp) 76245431Sdim char *cp; 77245431Sdim{ 78245431Sdim struct stat stb; 79239313Sdim 80245431Sdim if (!stat(cp, &stb)) { 81245431Sdim if (S_ISDIR(stb.st_mode)) 82239313Sdim return; 83239313Sdim errno = ENOTDIR; 84239313Sdim } 85239313Sdim run_err("%s: %s", cp, strerror(errno)); 86245431Sdim exit(1); 87245431Sdim} 88239313Sdim 89239313Sdimint 90239313Sdimokname(cp0) 91239313Sdim char *cp0; 92239313Sdim{ 93239313Sdim int c; 94239313Sdim char *cp; 95245431Sdim 96245431Sdim cp = cp0; 97245431Sdim do { 98245431Sdim c = *cp; 99245431Sdim if (c & 0200) 100245431Sdim goto bad; 101245431Sdim if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-') 102245431Sdim goto bad; 103239313Sdim } while (*++cp); 104239313Sdim return (1); 105239313Sdim 106239313Sdimbad: warnx("%s: invalid user name", cp0); 107239313Sdim return (0); 108239313Sdim} 109239313Sdim 110239313Sdimint 111239313Sdimsusystem(s, userid) 112239313Sdim int userid; 113239313Sdim char *s; 114239313Sdim{ 115239313Sdim sig_t istat, qstat; 116239313Sdim int status; 117239313Sdim pid_t pid; 118239313Sdim 119239313Sdim pid = vfork(); 120239313Sdim switch (pid) { 121239313Sdim case -1: 122239313Sdim return (127); 123239313Sdim 124245431Sdim case 0: 125239313Sdim (void)setuid(userid); 126239313Sdim execl(_PATH_BSHELL, "sh", "-c", s, NULL); 127239313Sdim _exit(127); 128239313Sdim } 129239313Sdim istat = signal(SIGINT, SIG_IGN); 130239313Sdim qstat = signal(SIGQUIT, SIG_IGN); 131239313Sdim if (waitpid(pid, &status, 0) < 0) 132239313Sdim status = -1; 133239313Sdim (void)signal(SIGINT, istat); 134239313Sdim (void)signal(SIGQUIT, qstat); 135239313Sdim return (status); 136239313Sdim} 137239313Sdim 138239313SdimBUF * 139239313Sdimallocbuf(bp, fd, blksize) 140239313Sdim BUF *bp; 141239313Sdim int fd, blksize; 142239313Sdim{ 143239313Sdim struct stat stb; 144239313Sdim size_t size; 145239313Sdim 146239313Sdim if (fstat(fd, &stb) < 0) { 147239313Sdim run_err("fstat: %s", strerror(errno)); 148239313Sdim return (0); 149239313Sdim } 150239313Sdim size = roundup(stb.st_blksize, blksize); 151239313Sdim if (size == 0) 152239313Sdim size = blksize; 153239313Sdim if (bp->cnt >= size) 154239313Sdim return (bp); 155239313Sdim if ((bp->buf = realloc(bp->buf, size)) == NULL) { 156239313Sdim bp->cnt = 0; 157239313Sdim run_err("%s", strerror(errno)); 158239313Sdim return (0); 159239313Sdim } 160239313Sdim bp->cnt = size; 161239313Sdim return (bp); 162239313Sdim} 163239313Sdim 164239313Sdimvoid 165252723Sdimlostconn(signo) 166239313Sdim int signo; 167239313Sdim{ 168239313Sdim if (!iamremote) 169252723Sdim warnx("lost connection"); 170239313Sdim exit(1); 171239313Sdim} 172239313Sdim