GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/bgplg/bgplgsh/../misc.c Lines: 0 62 0.0 %
Date: 2017-11-07 Branches: 0 31 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: misc.c,v 1.7 2017/07/27 20:01:05 florian 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
36
static volatile pid_t child = -1;
37
38
int
39
lg_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
48
int
49
lg_checkperm(struct cmd *cmd)
50
{
51
	struct stat stbuf;
52
53
	/* No external command to execute, this is always valid */
54
	if (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
69
int
70
lg_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
89
void
90
lg_sig_alarm(int sig)
91
{
92
	if (child != -1) {
93
		/* Forcibly kill the child, no excuse... */
94
		kill(child, SIGKILL);
95
	}
96
}
97
98
int
99
lg_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
160
ssize_t
161
lg_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
}