util.c revision 80818
133965Sjdp/*-
2130561Sobrien * Copyright (c) 1992, 1993
3218822Sdim *	The Regents of the University of California.  All rights reserved.
433965Sjdp *
577298Sobrien * Redistribution and use in source and binary forms, with or without
633965Sjdp * modification, are permitted provided that the following conditions
733965Sjdp * are met:
833965Sjdp * 1. Redistributions of source code must retain the above copyright
933965Sjdp *    notice, this list of conditions and the following disclaimer.
1033965Sjdp * 2. Redistributions in binary form must reproduce the above copyright
1133965Sjdp *    notice, this list of conditions and the following disclaimer in the
1233965Sjdp *    documentation and/or other materials provided with the distribution.
1333965Sjdp * 3. All advertising materials mentioning features or use of this software
1433965Sjdp *    must display the following acknowledgement:
1533965Sjdp *	This product includes software developed by the University of
1633965Sjdp *	California, Berkeley and its contributors.
1733965Sjdp * 4. Neither the name of the University nor the names of its contributors
1833965Sjdp *    may be used to endorse or promote products derived from this software
1960484Sobrien *    without specific prior written permission.
20218822Sdim *
21218822Sdim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2233965Sjdp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23218822Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2433965Sjdp * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2533965Sjdp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2689857Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2733965Sjdp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2833965Sjdp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2933965Sjdp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3033965Sjdp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3133965Sjdp * SUCH DAMAGE.
32107492Sobrien */
3333965Sjdp
3433965Sjdp#ifndef lint
3533965Sjdp#if 0
3633965Sjdpstatic char sccsid[] = "@(#)util.c	8.2 (Berkeley) 4/2/94";
3733965Sjdp#endif
3833965Sjdpstatic const char rcsid[] =
3933965Sjdp  "$FreeBSD: head/bin/rcp/util.c 80818 2001-08-01 05:12:39Z obrien $";
4060484Sobrien#endif /* not lint */
4160484Sobrien
4260484Sobrien#include <sys/param.h>
43130561Sobrien#include <sys/stat.h>
4460484Sobrien#include <sys/wait.h>
4533965Sjdp
4633965Sjdp#include <ctype.h>
4733965Sjdp#include <err.h>
4833965Sjdp#include <errno.h>
4933965Sjdp#include <paths.h>
5033965Sjdp#include <signal.h>
5133965Sjdp#include <stdio.h>
52218822Sdim#include <stdlib.h>
5333965Sjdp#include <string.h>
5433965Sjdp#include <unistd.h>
5533965Sjdp
56130561Sobrien#include "extern.h"
57130561Sobrien
58130561Sobrienchar *
59130561Sobriencolon(cp)
60130561Sobrien	char *cp;
6133965Sjdp{
6233965Sjdp	if (*cp == ':')		/* Leading colon is part of file name. */
6333965Sjdp		return (0);
6433965Sjdp
6533965Sjdp	for (; *cp; ++cp) {
66130561Sobrien		if (*cp == ':')
6733965Sjdp			return (cp);
6833965Sjdp		if (*cp == '/')
6933965Sjdp			return (0);
70130561Sobrien	}
7133965Sjdp	return (0);
72130561Sobrien}
7333965Sjdp
7433965Sjdpvoid
7533965Sjdpverifydir(cp)
7633965Sjdp	char *cp;
7733965Sjdp{
7833965Sjdp	struct stat stb;
7933965Sjdp
8033965Sjdp	if (!stat(cp, &stb)) {
8133965Sjdp		if (S_ISDIR(stb.st_mode))
8233965Sjdp			return;
8333965Sjdp		errno = ENOTDIR;
8477298Sobrien	}
8577298Sobrien	run_err("%s: %s", cp, strerror(errno));
8633965Sjdp	exit(1);
8733965Sjdp}
8833965Sjdp
8933965Sjdpint
9033965Sjdpokname(cp0)
9133965Sjdp	char *cp0;
9233965Sjdp{
9333965Sjdp	int c;
9433965Sjdp	char *cp;
9533965Sjdp
9633965Sjdp	cp = cp0;
9733965Sjdp	do {
9833965Sjdp		c = *cp;
9933965Sjdp		if (c & 0200)
10033965Sjdp			goto bad;
10133965Sjdp		if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-' && c != '.')
10260484Sobrien			goto bad;
10333965Sjdp	} while (*++cp);
10433965Sjdp	return (1);
10533965Sjdp
10633965Sjdpbad:	warnx("%s: invalid user name", cp0);
10733965Sjdp	return (0);
108130561Sobrien}
10933965Sjdp
11033965Sjdpint
11133965Sjdpsusystem(s, userid)
11233965Sjdp	int userid;
11333965Sjdp	char *s;
11433965Sjdp{
11533965Sjdp	sig_t istat, qstat;
11633965Sjdp	int status;
11733965Sjdp	pid_t pid;
11833965Sjdp
11933965Sjdp	pid = vfork();
12033965Sjdp	switch (pid) {
12160484Sobrien	case -1:
12260484Sobrien		return (127);
12360484Sobrien
12460484Sobrien	case 0:
125130561Sobrien		(void)setuid(userid);
12660484Sobrien		execl(_PATH_BSHELL, "sh", "-c", s, (char *)NULL);
12760484Sobrien		_exit(127);
12860484Sobrien	}
12960484Sobrien	istat = signal(SIGINT, SIG_IGN);
13060484Sobrien	qstat = signal(SIGQUIT, SIG_IGN);
13160484Sobrien	if (waitpid(pid, &status, 0) < 0)
13260484Sobrien		status = -1;
13360484Sobrien	(void)signal(SIGINT, istat);
134218822Sdim	(void)signal(SIGQUIT, qstat);
13560484Sobrien	return (status);
13660484Sobrien}
13760484Sobrien
13860484SobrienBUF *
13960484Sobrienallocbuf(bp, fd, blksize)
14060484Sobrien	BUF *bp;
14160484Sobrien	int fd, blksize;
14260484Sobrien{
14389857Sobrien	struct stat stb;
14460484Sobrien	size_t size;
14560484Sobrien
14660484Sobrien	if (fstat(fd, &stb) < 0) {
14760484Sobrien		run_err("fstat: %s", strerror(errno));
14860484Sobrien		return (0);
14960484Sobrien	}
15060484Sobrien	size = roundup(stb.st_blksize, blksize);
15160484Sobrien	if (size == 0)
15260484Sobrien		size = blksize;
153130561Sobrien	if (bp->cnt >= size)
15460484Sobrien		return (bp);
155130561Sobrien	if ((bp->buf = realloc(bp->buf, size)) == NULL) {
156130561Sobrien		bp->cnt = 0;
15760484Sobrien		run_err("%s", strerror(errno));
15860484Sobrien		return (0);
15960484Sobrien	}
16060484Sobrien	bp->cnt = size;
16160484Sobrien	return (bp);
16260484Sobrien}
16360484Sobrien
16460484Sobrienvoid
16560484Sobrienlostconn(signo)
16660484Sobrien	int signo;
16760484Sobrien{
16860484Sobrien	if (!iamremote)
16960484Sobrien		warnx("lost connection");
17060484Sobrien	exit(1);
17160484Sobrien}
17260484Sobrien