misc.c revision 1.6
1/*	$OpenBSD: misc.c,v 1.6 2013/11/25 18:02:50 deraadt Exp $	*/
2
3/*
4 * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/stat.h>
20#include <sys/types.h>
21#include <sys/utsname.h>
22#include <sys/wait.h>
23#include <sys/time.h>
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <signal.h>
28#include <string.h>
29#include <unistd.h>
30#include <ctype.h>
31#include <errno.h>
32#include <fcntl.h>
33
34#include "bgplg.h"
35
36static volatile pid_t child = -1;
37
38int
39lg_show_version(struct cmd *cmds, char **argv)
40{
41	struct utsname uts;
42	if (uname(&uts) >= 0)
43		printf("%s %s (%s)\n\n", uts.sysname, uts.release, uts.machine);
44	printf("%s - %s\n", NAME, BRIEF);
45	return (0);
46}
47
48int
49lg_checkperm(struct cmd *cmd)
50{
51	struct stat stbuf;
52
53	/* No external command to execute, this is always valid */
54	if (cmd->earg == NULL || cmd->earg[0] == NULL)
55		return (1);
56
57	/*
58	 * Skip commands if the executable is missing or
59	 * the permission mode has been set to zero (the default
60	 * in a CGI environment).
61	 */
62	if (stat(cmd->earg[0], &stbuf) != 0 ||
63	    (stbuf.st_mode & ~S_IFMT) == 0)
64		return (0);
65
66	return (1);
67}
68
69int
70lg_help(struct cmd *cmds, char **argv)
71{
72	u_int i;
73
74	printf("valid commands:\n");
75	for (i = 0; cmds[i].name != NULL; i++) {
76		if (!lg_checkperm(&cmds[i]))
77			continue;
78
79		printf("  %s", cmds[i].name);
80		if (cmds[i].minargs > 0)
81			printf(" { arg }");
82		else if (cmds[i].maxargs > 0)
83			printf(" [ arg ]");
84		printf("\n");
85	}
86	return (0);
87}
88
89void
90lg_sig_alarm(int sig)
91{
92	if (child != -1) {
93		/* Forcibly kill the child, no excuse... */
94		kill(child, SIGKILL);
95	}
96}
97
98int
99lg_exec(const char *file, char **new_argv)
100{
101	int status = 0, ret = 0;
102	sig_t save_quit, save_int, save_chld;
103	struct itimerval it;
104
105	if (new_argv == NULL)
106		return (EFAULT);
107
108	save_quit = signal(SIGQUIT, SIG_IGN);
109	save_int = signal(SIGINT, SIG_IGN);
110	save_chld = signal(SIGCHLD, SIG_DFL);
111
112	switch (child = fork()) {
113	case -1:
114		ret = errno;
115		goto done;
116	case 0:
117		signal(SIGQUIT, SIG_DFL);
118		signal(SIGINT, SIG_DFL);
119		signal(SIGCHLD, SIG_DFL);
120
121		execvp(file, new_argv);
122		_exit(127);
123		break;
124	default:
125		/* Kill the process after a timeout */
126		signal(SIGALRM, lg_sig_alarm);
127		bzero(&it, sizeof(it));
128		it.it_value.tv_sec = BGPLG_TIMEOUT;
129		setitimer(ITIMER_REAL, &it, NULL);
130
131		waitpid(child, &status, 0);
132		break;
133	}
134
135	switch (ret) {
136	case -1:
137		ret = ECHILD;
138		break;
139	default:
140		if (WIFEXITED(status))
141			ret = WEXITSTATUS(status);
142		else
143			ret = ECHILD;
144	}
145
146 done:
147	/* Disable the process timeout timer */
148	bzero(&it, sizeof(it));
149	setitimer(ITIMER_REAL, &it, NULL);
150	child = -1;
151
152	signal(SIGQUIT, save_quit);
153	signal(SIGINT, save_int);
154	signal(SIGCHLD, save_chld);
155	signal(SIGALRM, SIG_DFL);
156
157	return (ret);
158}
159
160ssize_t
161lg_strip(char *str)
162{
163	size_t len;
164
165	if ((len = strlen(str)) < 1)
166		return (0); /* XXX EINVAL? */
167
168	if (isspace((unsigned char)str[len - 1])) {
169		str[len - 1] = '\0';
170		return (lg_strip(str));
171	}
172
173	return (strlen(str));
174}
175