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