Blame src/util.c

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
}