|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* util.c Little helper routines that didn't fit anywhere else.
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* This file is part of the minicom communications package,
|
|
Packit |
15a96c |
* Copyright 1991-1995 Miquel van Smoorenburg.
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* This program is free software; you can redistribute it and/or
|
|
Packit |
15a96c |
* modify it under the terms of the GNU General Public License
|
|
Packit |
15a96c |
* as published by the Free Software Foundation; either version
|
|
Packit |
15a96c |
* 2 of the License, or (at your option) any later version.
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* You should have received a copy of the GNU General Public License along
|
|
Packit |
15a96c |
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
Packit |
15a96c |
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* jseymour@jimsun.LinxNet.com (Jim Seymour) 03/26/98 - Added get_port()
|
|
Packit |
15a96c |
* function to support multiple port specifications in config.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
#ifdef HAVE_CONFIG_H
|
|
Packit |
15a96c |
#include <config.h>
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
#include "port.h"
|
|
Packit |
15a96c |
#include "minicom.h"
|
|
Packit |
15a96c |
#include "intl.h"
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* A modified version of the getargs routine.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
static int getargs(char *s, char **arps, int maxargs)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
register int i;
|
|
Packit |
15a96c |
register char *sp;
|
|
Packit |
15a96c |
register char qchar;
|
|
Packit |
15a96c |
int literal = 0;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
i = 0;
|
|
Packit |
15a96c |
while (i < maxargs) {
|
|
Packit |
15a96c |
while (*s == ' ' || *s == '\t')
|
|
Packit |
15a96c |
++s;
|
|
Packit |
15a96c |
if (*s == '\n' || *s == '\0')
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
arps[i++] = sp = s;
|
|
Packit |
15a96c |
qchar = 0;
|
|
Packit |
15a96c |
while(*s != '\0' && *s != '\n') {
|
|
Packit |
15a96c |
if (literal) {
|
|
Packit |
15a96c |
literal = 0;
|
|
Packit |
15a96c |
*sp++ = *s++;
|
|
Packit |
15a96c |
continue;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
literal = 0;
|
|
Packit |
15a96c |
if (qchar == 0 && (*s == ' ' || *s == '\t')) {
|
|
Packit |
15a96c |
++s;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
switch(*s) {
|
|
Packit |
15a96c |
default:
|
|
Packit |
15a96c |
*sp++ = *s++;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case '\\':
|
|
Packit |
15a96c |
literal = 1;
|
|
Packit |
15a96c |
s++;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
case '"':
|
|
Packit |
15a96c |
case '\'':
|
|
Packit |
15a96c |
if(qchar == *s) {
|
|
Packit |
15a96c |
qchar = 0;
|
|
Packit |
15a96c |
++s;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if(qchar)
|
|
Packit |
15a96c |
*sp++ = *s++;
|
|
Packit |
15a96c |
else
|
|
Packit |
15a96c |
qchar = *s++;
|
|
Packit |
15a96c |
break;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
*sp++ = 0;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (i >= maxargs)
|
|
Packit |
15a96c |
return -1;
|
|
Packit |
15a96c |
arps[i] = NULL;
|
|
Packit |
15a96c |
return i;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* Is a character from s2 in s1?
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
#if 0
|
|
Packit |
15a96c |
static int anys(const char *s1, const char *s2)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
while (*s2)
|
|
Packit |
15a96c |
if (strchr(s1, *s2++))
|
|
Packit |
15a96c |
return 1;
|
|
Packit |
15a96c |
return 0;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* If there is a shell-metacharacter in "cmd",
|
|
Packit |
15a96c |
* call a shell to do the dirty work.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
int fastexec(char *cmd)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
char *words[128];
|
|
Packit |
15a96c |
char *p;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* This is potentially security relevant (e.g. user selects a file
|
|
Packit |
15a96c |
* with embedded shellcode for upload), so disable it for now and
|
|
Packit |
15a96c |
* see if someone complains. 27. 09. 2003 */
|
|
Packit |
15a96c |
#if 0
|
|
Packit |
15a96c |
if (anys(cmd, "~`$&*()=|{};?><"))
|
|
Packit |
15a96c |
return execl("/bin/sh", "sh", "-c", cmd, NULL);
|
|
Packit |
15a96c |
#endif
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Delete escape-characters ment for the shell */
|
|
Packit |
15a96c |
p = cmd;
|
|
Packit |
15a96c |
while ((p = strchr(p, '\\')) && *(p+1) != ' ')
|
|
Packit |
15a96c |
memmove(p, p + 1, strlen(p+1));
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Split line into words */
|
|
Packit |
15a96c |
if (getargs(cmd, words, 127) < 0)
|
|
Packit |
15a96c |
return -1;
|
|
Packit |
15a96c |
return execvp(words[0], words);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* Fork, then redirect I/O if neccesary.
|
|
Packit |
15a96c |
* in : new stdin
|
|
Packit |
15a96c |
* out : new stdout
|
|
Packit |
15a96c |
* err : new stderr
|
|
Packit |
15a96c |
* Returns exit status of "cmd" on success, -1 on error.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
int fastsystem(char *cmd, char *in, char *out, char *err)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
int pid;
|
|
Packit |
15a96c |
int st;
|
|
Packit |
15a96c |
int async = 0;
|
|
Packit |
15a96c |
char *p;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* If the command line ends with '&', don't wait for child. */
|
|
Packit |
15a96c |
p = strrchr(cmd, '&';;
|
|
Packit |
15a96c |
if (p != (char *)0 && !p[1]) {
|
|
Packit |
15a96c |
*p = 0;
|
|
Packit |
15a96c |
async = 1;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* Fork. */
|
|
Packit |
15a96c |
if ((pid = fork()) == 0) { /* child */
|
|
Packit |
15a96c |
if (in) {
|
|
Packit |
15a96c |
close(0);
|
|
Packit |
15a96c |
if (open(in, O_RDONLY) < 0)
|
|
Packit |
15a96c |
exit(-1);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (out) {
|
|
Packit |
15a96c |
close(1);
|
|
Packit |
15a96c |
if (open(out, O_WRONLY) < 0)
|
|
Packit |
15a96c |
exit(-1);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
if (err) {
|
|
Packit |
15a96c |
close(2);
|
|
Packit |
15a96c |
if (open(err, O_RDWR) < 0)
|
|
Packit |
15a96c |
exit(-1);
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
exit(fastexec(cmd));
|
|
Packit |
15a96c |
} else if (pid > 0) { /* parent */
|
|
Packit |
15a96c |
if (async)
|
|
Packit |
15a96c |
return 0;
|
|
Packit |
15a96c |
pid = m_wait(&st);
|
|
Packit |
15a96c |
if (pid < 0)
|
|
Packit |
15a96c |
return -1;
|
|
Packit |
15a96c |
return st;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
return -1;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/*
|
|
Packit |
15a96c |
* Get next port from a space-, comma-, or semi-colon-separated
|
|
Packit |
15a96c |
* list (we're easy :-)) in a PARS_VAL_LEN length string.
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* Returns NULL pointer on end-of-list.
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* This would appear to be more complicated than it needs be.
|
|
Packit |
15a96c |
*
|
|
Packit |
15a96c |
* WARNING: Not MT-safe. Multiple calls to this routine modify the same
|
|
Packit |
15a96c |
* local static storage space.
|
|
Packit |
15a96c |
*/
|
|
Packit |
15a96c |
char * get_port(char *port_list)
|
|
Packit |
15a96c |
{
|
|
Packit |
15a96c |
static char next_port[PARS_VAL_LEN];
|
|
Packit |
15a96c |
static char loc_port_list[PARS_VAL_LEN];
|
|
Packit |
15a96c |
static char *sp = NULL;
|
|
Packit |
15a96c |
static char *ep;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
/* first pass? */
|
|
Packit |
15a96c |
if (sp == NULL) {
|
|
Packit |
15a96c |
strncpy(loc_port_list, port_list, PARS_VAL_LEN);
|
|
Packit |
15a96c |
loc_port_list[PARS_VAL_LEN - 1] = 0;
|
|
Packit |
15a96c |
ep = &loc_port_list[strlen(loc_port_list)];
|
|
Packit |
15a96c |
sp = strtok(loc_port_list, ";, ");
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
else if (*sp != 0)
|
|
Packit |
15a96c |
sp = strtok(sp, ";, ");
|
|
Packit |
15a96c |
else
|
|
Packit |
15a96c |
sp = NULL;
|
|
Packit |
15a96c |
|
|
Packit |
15a96c |
if (sp != NULL) {
|
|
Packit |
15a96c |
strncpy(next_port, sp, PARS_VAL_LEN);
|
|
Packit |
15a96c |
next_port[PARS_VAL_LEN - 1] = 0;
|
|
Packit |
15a96c |
/* point to next token--skipping multiple occurrences of delimiters */
|
|
Packit |
15a96c |
for (sp += strlen(next_port); sp != ep && *sp != '/'; ++sp)
|
|
Packit |
15a96c |
;
|
|
Packit |
15a96c |
return next_port;
|
|
Packit |
15a96c |
}
|
|
Packit |
15a96c |
else
|
|
Packit |
15a96c |
return NULL;
|
|
Packit |
15a96c |
}
|