[BACK]Return to misc.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / bgplg

Annotation of src/usr.bin/bgplg/misc.c, Revision 1.8

1.8     ! job         1: /*     $OpenBSD: misc.c,v 1.7 2017/07/27 20:01:05 florian Exp $        */
1.1       reyk        2:
                      3: /*
1.5       reyk        4:  * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
1.1       reyk        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_checkperm(struct cmd *cmd)
                     40: {
                     41:        struct stat stbuf;
                     42:
                     43:        /* No external command to execute, this is always valid */
1.7       florian    44:        if (cmd->earg[0] == NULL)
1.1       reyk       45:                return (1);
                     46:
                     47:        /*
                     48:         * Skip commands if the executable is missing or
                     49:         * the permission mode has been set to zero (the default
                     50:         * in a CGI environment).
                     51:         */
                     52:        if (stat(cmd->earg[0], &stbuf) != 0 ||
                     53:            (stbuf.st_mode & ~S_IFMT) == 0)
                     54:                return (0);
                     55:
                     56:        return (1);
                     57: }
                     58:
                     59: int
                     60: lg_help(struct cmd *cmds, char **argv)
                     61: {
                     62:        u_int i;
                     63:
                     64:        printf("valid commands:\n");
                     65:        for (i = 0; cmds[i].name != NULL; i++) {
                     66:                if (!lg_checkperm(&cmds[i]))
                     67:                        continue;
                     68:
                     69:                printf("  %s", cmds[i].name);
                     70:                if (cmds[i].minargs > 0)
                     71:                        printf(" { arg }");
                     72:                else if (cmds[i].maxargs > 0)
                     73:                        printf(" [ arg ]");
                     74:                printf("\n");
                     75:        }
                     76:        return (0);
                     77: }
                     78:
                     79: void
                     80: lg_sig_alarm(int sig)
                     81: {
                     82:        if (child != -1) {
1.3       sthen      83:                /* Forcibly kill the child, no excuse... */
1.1       reyk       84:                kill(child, SIGKILL);
                     85:        }
                     86: }
                     87:
                     88: int
                     89: lg_exec(const char *file, char **new_argv)
                     90: {
                     91:        int status = 0, ret = 0;
                     92:        sig_t save_quit, save_int, save_chld;
                     93:        struct itimerval it;
                     94:
                     95:        if (new_argv == NULL)
                     96:                return (EFAULT);
                     97:
                     98:        save_quit = signal(SIGQUIT, SIG_IGN);
                     99:        save_int = signal(SIGINT, SIG_IGN);
                    100:        save_chld = signal(SIGCHLD, SIG_DFL);
                    101:
                    102:        switch (child = fork()) {
                    103:        case -1:
                    104:                ret = errno;
                    105:                goto done;
                    106:        case 0:
                    107:                signal(SIGQUIT, SIG_DFL);
                    108:                signal(SIGINT, SIG_DFL);
                    109:                signal(SIGCHLD, SIG_DFL);
                    110:
                    111:                execvp(file, new_argv);
                    112:                _exit(127);
                    113:                break;
                    114:        default:
                    115:                /* Kill the process after a timeout */
                    116:                signal(SIGALRM, lg_sig_alarm);
                    117:                bzero(&it, sizeof(it));
                    118:                it.it_value.tv_sec = BGPLG_TIMEOUT;
                    119:                setitimer(ITIMER_REAL, &it, NULL);
1.2       reyk      120:
1.1       reyk      121:                waitpid(child, &status, 0);
                    122:                break;
                    123:        }
                    124:
                    125:        switch (ret) {
                    126:        case -1:
                    127:                ret = ECHILD;
                    128:                break;
                    129:        default:
                    130:                if (WIFEXITED(status))
                    131:                        ret = WEXITSTATUS(status);
                    132:                else
                    133:                        ret = ECHILD;
                    134:        }
                    135:
                    136:  done:
                    137:        /* Disable the process timeout timer */
                    138:        bzero(&it, sizeof(it));
                    139:        setitimer(ITIMER_REAL, &it, NULL);
                    140:        child = -1;
                    141:
                    142:        signal(SIGQUIT, save_quit);
                    143:        signal(SIGINT, save_int);
                    144:        signal(SIGCHLD, save_chld);
                    145:        signal(SIGALRM, SIG_DFL);
                    146:
                    147:        return (ret);
                    148: }
                    149:
                    150: ssize_t
                    151: lg_strip(char *str)
                    152: {
                    153:        size_t len;
                    154:
                    155:        if ((len = strlen(str)) < 1)
                    156:                return (0); /* XXX EINVAL? */
                    157:
1.6       deraadt   158:        if (isspace((unsigned char)str[len - 1])) {
1.1       reyk      159:                str[len - 1] = '\0';
                    160:                return (lg_strip(str));
                    161:        }
                    162:
                    163:        return (strlen(str));
                    164: }