[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.5

1.5     ! reyk        1: /*     $OpenBSD: misc.c,v 1.4 2011/04/19 23:54:00 matthew 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_show_version(struct cmd *cmds, char **argv)
                     40: {
                     41:        struct utsname uts;
1.4       matthew    42:        if (uname(&uts) >= 0)
1.1       reyk       43:                printf("%s %s (%s)\n\n", uts.sysname, uts.release, uts.machine);
                     44:        printf("%s - %s\n", NAME, BRIEF);
1.2       reyk       45:        return (0);
1.1       reyk       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 == 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:
                     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) {
1.3       sthen      93:                /* Forcibly kill the child, no excuse... */
1.1       reyk       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);
1.2       reyk      130:
1.1       reyk      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(str[len - 1])) {
                    169:                str[len - 1] = '\0';
                    170:                return (lg_strip(str));
                    171:        }
                    172:
                    173:        return (strlen(str));
                    174: }