Blame src/script.c

Packit 15a96c
/*
Packit 15a96c
 * Runscript    Run a login-or-something script.
Packit 15a96c
 *		A basic like "programming language".
Packit 15a96c
 *		This program also looks like a basic interpreter :
Packit 15a96c
 *		a bit messy. (But hey, I'm no compiler writer :-))
Packit 15a96c
 *
Packit 15a96c
 * Author:	Miquel van Smoorenburg, miquels@drinkel.ow.nl
Packit 15a96c
 *
Packit 15a96c
 * Bugs:	The "expect" routine is, unlike gosub, NOT reentrant !
Packit 15a96c
 *
Packit 15a96c
 *		This file is part of the minicom communications package,
Packit 15a96c
 *		Copyright 1991-1995 Miquel van Smoorenburg,
Packit 15a96c
 *		1997-1999 Jukka Lahtinen
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
 * 10.07.98 jl  Added the log command
Packit 15a96c
 * 05.04.99 jl  The logfile name should also be passed as a parameter
Packit 15a96c
 * 04.03.2002 jl Treat the ^ character between quotes as control code prefix
Packit 15a96c
 * 10.09.2013 ts Support sending the null character
Packit 15a96c
 * 10.10.2013 ts Add the pipedshell command
Packit 15a96c
 */
Packit 15a96c
Packit 15a96c
#ifdef HAVE_CONFIG_H
Packit 15a96c
#include <config.h>
Packit 15a96c
#endif
Packit 15a96c
Packit 15a96c
#include <stdarg.h>
Packit 15a96c
Packit 15a96c
#include "port.h"
Packit 15a96c
#include "minicom.h"
Packit 15a96c
#include "intl.h"
Packit 15a96c
Packit 15a96c
#define OK	0
Packit 15a96c
#define ERR	-1
Packit 15a96c
#define RETURN	1
Packit 15a96c
#define BREAK	2
Packit 15a96c
Packit 15a96c
enum {
Packit 15a96c
  NULL_CHARACTER = 254,
Packit 15a96c
  SKIP_NEWLINE   = 255,
Packit 15a96c
};
Packit 15a96c
Packit 15a96c
struct line {
Packit 15a96c
  char *line;
Packit 15a96c
  int labelcount;
Packit 15a96c
  int lineno;
Packit 15a96c
  struct line *next;
Packit 15a96c
};
Packit 15a96c
Packit 15a96c
struct var {
Packit 15a96c
  char *name;
Packit 15a96c
  int value;
Packit 15a96c
  struct var *next;
Packit 15a96c
};
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Structure describing the script we are currently executing.
Packit 15a96c
 */
Packit 15a96c
struct env {
Packit 15a96c
  struct line *lines;		/* Start of all lines */
Packit 15a96c
  struct var *vars;		/* Start of all variables */
Packit 15a96c
  const char *scriptname;	/* Name of this script */
Packit 15a96c
  int verbose;			/* Are we verbose? */
Packit 15a96c
  jmp_buf ebuf;			/* For exit */
Packit 15a96c
  int exstat;			/* For exit */
Packit 15a96c
};
Packit 15a96c
Packit 15a96c
struct env *curenv;		/* Execution environment */
Packit 15a96c
int gtimeout = 120;		/* Global Timeout */
Packit 15a96c
int etimeout = 0;		/* Timeout in expect routine */
Packit 15a96c
jmp_buf ejmp;			/* To jump to if expect times out */
Packit 15a96c
int inexpect = 0;		/* Are we in the expect routine */
Packit 15a96c
const char *newline;		/* What to print for '\n'. */
Packit 15a96c
const char *s_login = "name";	/* User's login name */
Packit 15a96c
const char *s_pass = "password";/* User's password */
Packit 15a96c
struct line *thisline;		/* Line to be executed */
Packit 15a96c
int laststatus = 0;		/* Status of last command */
Packit 15a96c
char homedir[256];		/* Home directory */
Packit 15a96c
char logfname[PARS_VAL_LEN];	/* Name of logfile */
Packit 15a96c
Packit 15a96c
static char inbuf[65];		/* Input buffer. */
Packit 15a96c
Packit 15a96c
/* Forward declarations */
Packit 15a96c
int s_exec(char *);
Packit 15a96c
int execscript(const char *);
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Walk through the environment, see if LOGIN and/or PASS are present.
Packit 15a96c
 * If so, delete them. (Someone using "ps" might see them!)
Packit 15a96c
 */
Packit 15a96c
void init_env(void)
Packit 15a96c
{
Packit 15a96c
  extern char **environ;
Packit 15a96c
  char **e;
Packit 15a96c
Packit 15a96c
  for (e = environ; *e; e++) {
Packit 15a96c
    if (!strncmp(*e, "LOGIN=", 6)) {
Packit 15a96c
      s_login = *e + 6;
Packit 15a96c
      *e = "LOGIN=";
Packit 15a96c
    }
Packit 15a96c
    if (!strncmp(*e, "PASS=", 5)) {
Packit 15a96c
      s_pass = *e + 5;
Packit 15a96c
      *e = "PASS=";
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Return an environment variable.
Packit 15a96c
 */
Packit 15a96c
const char *mygetenv(char *env)
Packit 15a96c
{
Packit 15a96c
  if (!strcmp(env, "LOGIN"))
Packit 15a96c
    return s_login;
Packit 15a96c
  if (!strcmp(env, "PASS"))
Packit 15a96c
    return s_pass;
Packit 15a96c
  return getenv(env);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Display a syntax error and exit.
Packit 15a96c
 */
Packit 15a96c
void syntaxerr(const char *s)
Packit 15a96c
{
Packit 15a96c
  fprintf(stderr, _("script \"%s\": syntax error in line %d %s%s\n"),
Packit 15a96c
          curenv->scriptname, thisline->lineno, s, "\r");
Packit 15a96c
  exit(1);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Skip all space
Packit 15a96c
 */
Packit 15a96c
void skipspace(char **s)
Packit 15a96c
{
Packit 15a96c
  while (**s == ' ' || **s == '\t')
Packit 15a96c
    (*s)++;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Our clock. This gets called every second.
Packit 15a96c
 */
Packit 15a96c
void myclock(int dummy)
Packit 15a96c
{
Packit 15a96c
  (void)dummy;
Packit 15a96c
  signal(SIGALRM, myclock);
Packit 15a96c
  alarm(1);
Packit 15a96c
Packit 15a96c
  if (--gtimeout == 0) {
Packit 15a96c
    fprintf(stderr, _("script \"%s\": global timeout%s\n"),
Packit 15a96c
            curenv->scriptname,"\r");
Packit 15a96c
    exit(1);
Packit 15a96c
  }
Packit 15a96c
  if (inexpect && etimeout && --etimeout == 0)
Packit 15a96c
    siglongjmp(ejmp, 1);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
static char *buffer; /* The buffer is only growing and never freed... */
Packit 15a96c
static unsigned buffersize;
Packit 15a96c
Packit 15a96c
static void buf_wr(unsigned idx, char val)
Packit 15a96c
{
Packit 15a96c
  if (idx >= buffersize)
Packit 15a96c
    {
Packit 15a96c
      buffersize += 64;
Packit 15a96c
      buffer = realloc(buffer, buffersize);
Packit 15a96c
    }
Packit 15a96c
  buffer[idx] = val;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
static inline char buf_rd(unsigned idx)
Packit 15a96c
{
Packit 15a96c
  return buffer[idx];
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
static unsigned bufsize()
Packit 15a96c
{
Packit 15a96c
  return buffersize;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
static inline char *buf()
Packit 15a96c
{
Packit 15a96c
  return buffer;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Read a word and advance pointer.
Packit 15a96c
 * Also processes quoting, variable substituting, and \ escapes.
Packit 15a96c
 */
Packit 15a96c
char *getword(char **s)
Packit 15a96c
{
Packit 15a96c
  unsigned int len;
Packit 15a96c
  int f;
Packit 15a96c
  int idx = 0;
Packit 15a96c
  const char *t = *s;
Packit 15a96c
  int sawesc = 0;
Packit 15a96c
  int sawq = 0;
Packit 15a96c
  const char *env;
Packit 15a96c
  char envbuf[32];
Packit 15a96c
Packit 15a96c
  if (**s == 0)
Packit 15a96c
    return NULL;
Packit 15a96c
Packit 15a96c
  for (len = 0; ; len++) {
Packit 15a96c
    if (sawesc && t[len]) {
Packit 15a96c
      sawesc = 0;
Packit 15a96c
      if (t[len] <= '7' && t[len] >= '0') {
Packit 15a96c
        buf_wr(idx, 0);
Packit 15a96c
        for (f = 0; f < 4 && len < bufsize() && t[len] <= '7' &&
Packit 15a96c
             t[len] >= '0'; f++)
Packit 15a96c
          buf_wr(idx, 8 * buf_rd(idx) + t[len++] - '0');
Packit 15a96c
        if (buf_rd(idx) == 0)
Packit 15a96c
          buf_wr(idx, NULL_CHARACTER);
Packit 15a96c
        idx++;
Packit 15a96c
        len--;
Packit 15a96c
        continue;
Packit 15a96c
      }
Packit 15a96c
      switch (t[len]) {
Packit 15a96c
        case 'r':
Packit 15a96c
          buf_wr(idx++, '\r');
Packit 15a96c
          break;
Packit 15a96c
        case 'n':
Packit 15a96c
          buf_wr(idx++, '\n');
Packit 15a96c
          break;
Packit 15a96c
        case 'b':
Packit 15a96c
          buf_wr(idx++, '\b');
Packit 15a96c
          break;
Packit 15a96c
        case 'a':
Packit 15a96c
          buf_wr(idx++, '\a');
Packit 15a96c
          break;
Packit 15a96c
        case 'f':
Packit 15a96c
          buf_wr(idx++, '\f');
Packit 15a96c
          break;
Packit 15a96c
        case 'c':
Packit 15a96c
          buf_wr(idx++, SKIP_NEWLINE);
Packit 15a96c
          break;
Packit 15a96c
        default:
Packit 15a96c
          buf_wr(idx++, t[len]);
Packit 15a96c
          break;
Packit 15a96c
      }
Packit 15a96c
      sawesc = 0;
Packit 15a96c
      continue;
Packit 15a96c
    }
Packit 15a96c
    if (t[len] == '\\') {
Packit 15a96c
      sawesc = 1;
Packit 15a96c
      continue;
Packit 15a96c
    }
Packit 15a96c
    if (t[len] == '"') {
Packit 15a96c
      if (sawq == 1) {
Packit 15a96c
        sawq = 0;
Packit 15a96c
        len++;
Packit 15a96c
        break;
Packit 15a96c
      }
Packit 15a96c
      sawq = 1;
Packit 15a96c
      continue;
Packit 15a96c
    }
Packit 15a96c
    if (t[len] == '$' && t[len + 1] == '(') {
Packit 15a96c
      for(f = len; t[f] && t[f] != ')'; f++)
Packit 15a96c
        ;
Packit 15a96c
      if (t[f] == ')') {
Packit 15a96c
        strncpy(envbuf, &t[len + 2], f - len - 2);
Packit 15a96c
        envbuf[f - len - 2] = 0;
Packit 15a96c
        len = f;
Packit 15a96c
        env = mygetenv(envbuf);
Packit 15a96c
        if (env == NULL)
Packit 15a96c
          env = "";
Packit 15a96c
        while (*env)
Packit 15a96c
          buf_wr(idx++, *env++);
Packit 15a96c
        continue;
Packit 15a96c
      }
Packit 15a96c
    }
Packit 15a96c
    /* ^ prefix for control chars - jl 3.2002 */
Packit 15a96c
    if (sawq == 1 && t[len] == '^' && t[len + 1] != 0) {
Packit 15a96c
      char c = toupper(t[len + 1]);
Packit 15a96c
      if (c >= 'A' && c <= '_') {
Packit 15a96c
        len++;
Packit 15a96c
        buf_wr(idx++, c - 'A' + 1);
Packit 15a96c
        continue;
Packit 15a96c
      }
Packit 15a96c
    }
Packit 15a96c
    if ((!sawq && (t[len] == ' ' || t[len] == '\t')) || t[len] == 0)
Packit 15a96c
      break;
Packit 15a96c
    buf_wr(idx++, t[len]);
Packit 15a96c
  }
Packit 15a96c
  buf_wr(idx, 0);
Packit 15a96c
  *s += len;
Packit 15a96c
  skipspace(s);
Packit 15a96c
  if (sawesc || sawq)
Packit 15a96c
    syntaxerr(_("(word contains ESC or quote)"));
Packit 15a96c
  return buf();
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Save a string to memory. Strip trailing '\n'.
Packit 15a96c
 */
Packit 15a96c
char *strsave(char *s)
Packit 15a96c
{
Packit 15a96c
  char *t;
Packit 15a96c
  int len;
Packit 15a96c
Packit 15a96c
  len = strlen(s);
Packit 15a96c
  if (len && s[len - 1] == '\n')
Packit 15a96c
    s[--len] = 0;
Packit 15a96c
  if (!(t = malloc(len + 1)))
Packit 15a96c
    return t;
Packit 15a96c
  strcpy(t, s);
Packit 15a96c
  return t;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Throw away all malloced memory.
Packit 15a96c
 */
Packit 15a96c
void freemem(void)
Packit 15a96c
{
Packit 15a96c
  struct line *l, *nextl;
Packit 15a96c
  struct var *v, *nextv;
Packit 15a96c
Packit 15a96c
  for (l = curenv->lines; l; l = nextl) {
Packit 15a96c
    nextl = l->next;
Packit 15a96c
    free(l->line);
Packit 15a96c
    free(l);
Packit 15a96c
  }
Packit 15a96c
  for (v = curenv->vars; v; v = nextv) {
Packit 15a96c
    nextv = v->next;
Packit 15a96c
    free(v->name);
Packit 15a96c
    free(v);
Packit 15a96c
  }
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Read a script into memory.
Packit 15a96c
 */
Packit 15a96c
static int readscript(const char *s)
Packit 15a96c
{
Packit 15a96c
  FILE *fp;
Packit 15a96c
  struct line *tl, *prev = NULL;
Packit 15a96c
  char *t;
Packit 15a96c
  char buf[500]; /* max length of a line - this should be dynamically! */
Packit 15a96c
  int lineno = 0;
Packit 15a96c
Packit 15a96c
  if ((fp = fopen(s, "r")) == NULL) {
Packit 15a96c
    fprintf(stderr, _("runscript: couldn't open \"%s\"%s\n"), s, "\r");
Packit 15a96c
    exit(1);
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Read all the lines into a linked list in memory. */
Packit 15a96c
  while ((t = fgets(buf, sizeof(buf), fp)) != NULL) {
Packit 15a96c
    lineno++;
Packit 15a96c
    if (strlen(t) == sizeof(buf) - 1) {
Packit 15a96c
      /* Wow, this is really braindead, once upon a time buf was 81 chars
Packit 15a96c
       * big and triggered nice errors for too long input lines, now
Packit 15a96c
       * we just enlarge the buffer and add a sanity check. This code
Packit 15a96c
       * needs to allocate memory dynamically... */
Packit 15a96c
      fprintf(stderr, "Input line %u too long, aborting (and fix me!)!\n",
Packit 15a96c
	      lineno);
Packit 15a96c
      exit(1);
Packit 15a96c
    }
Packit 15a96c
    skipspace(&t);
Packit 15a96c
    if (*t == '\n' || *t == '#')
Packit 15a96c
      continue;
Packit 15a96c
    if (((tl = (struct line *)malloc(sizeof (struct line))) == NULL) ||
Packit 15a96c
        ((tl->line = strsave(t)) == NULL)) {
Packit 15a96c
      fprintf(stderr, _("script \"%s\": out of memory%s\n"), s, "\r");
Packit 15a96c
      exit(1);
Packit 15a96c
    }
Packit 15a96c
    if (prev)
Packit 15a96c
      prev->next = tl;
Packit 15a96c
    else
Packit 15a96c
      curenv->lines = tl;
Packit 15a96c
    tl->next = NULL;
Packit 15a96c
    tl->labelcount = 0;
Packit 15a96c
    tl->lineno = lineno;
Packit 15a96c
    prev = tl;
Packit 15a96c
  }
Packit 15a96c
  fclose(fp);
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/* Read one character, and store it in the buffer. */
Packit 15a96c
void readchar(void)
Packit 15a96c
{
Packit 15a96c
  char c;
Packit 15a96c
  int n;
Packit 15a96c
Packit 15a96c
  while ((n = read(0, &c, 1)) != 1)
Packit 15a96c
    if (errno != EINTR)
Packit 15a96c
      break;
Packit 15a96c
Packit 15a96c
  if (n <= 0)
Packit 15a96c
    return;
Packit 15a96c
Packit 15a96c
  /* Shift character into the buffer. */
Packit 15a96c
#ifdef _SYSV
Packit 15a96c
  memcpy(inbuf, inbuf + 1, 63);
Packit 15a96c
#else
Packit 15a96c
#  ifdef _BSD43
Packit 15a96c
  bcopy(inbuf + 1, inbuf, 63);
Packit 15a96c
#  else
Packit 15a96c
  /* This is Posix, I believe. */
Packit 15a96c
  memmove(inbuf, inbuf + 1, 63);
Packit 15a96c
#  endif
Packit 15a96c
#endif
Packit 15a96c
  if (curenv->verbose)
Packit 15a96c
    fputc(c, stderr);
Packit 15a96c
  inbuf[63] = c;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/* See if a string just came in. */
Packit 15a96c
int expfound(const char *word)
Packit 15a96c
{
Packit 15a96c
  int len;
Packit 15a96c
Packit 15a96c
  if (word == NULL) {
Packit 15a96c
    fprintf(stderr, "NULL paramenter to %s!", __func__);
Packit 15a96c
    exit(1);
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  len = strlen(word);
Packit 15a96c
  if (len > 64)
Packit 15a96c
    len = 64;
Packit 15a96c
Packit 15a96c
  return !strcmp(inbuf + 64 - len, word);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Send text to a file (stdout or stderr).
Packit 15a96c
 */
Packit 15a96c
int output(char *text, FILE *fp)
Packit 15a96c
{
Packit 15a96c
  unsigned char *w;
Packit 15a96c
  int first = 1;
Packit 15a96c
  int donl = 1;
Packit 15a96c
Packit 15a96c
  while ((w = (unsigned char *)getword(&text)) != NULL) {
Packit 15a96c
    if (!first)
Packit 15a96c
      fputc(' ', fp);
Packit 15a96c
    first = 0;
Packit 15a96c
    for(; *w; w++) {
Packit 15a96c
      if (*w == SKIP_NEWLINE) {
Packit 15a96c
        donl = 0;
Packit 15a96c
        continue;
Packit 15a96c
      }
Packit 15a96c
      if (*w == '\n')
Packit 15a96c
        fputs(newline, fp);
Packit 15a96c
      else if (*w == NULL_CHARACTER)
Packit 15a96c
        fputc('\0', fp);
Packit 15a96c
      else
Packit 15a96c
        fputc(*w, fp);
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
  if (donl)
Packit 15a96c
    fputs(newline, fp);
Packit 15a96c
  fflush(fp);
Packit 15a96c
  return OK;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Find a variable in the list.
Packit 15a96c
 * If it is not there, create it.
Packit 15a96c
 */
Packit 15a96c
struct var *getvar(char *name, int cr)
Packit 15a96c
{
Packit 15a96c
  struct var *v, *end = NULL;
Packit 15a96c
Packit 15a96c
  for (v = curenv->vars; v; v = v->next) {
Packit 15a96c
    end = v;
Packit 15a96c
    if (!strcmp(v->name, name))
Packit 15a96c
      return v;
Packit 15a96c
  }
Packit 15a96c
  if (!cr) {
Packit 15a96c
    fprintf(stderr, _("script \"%s\" line %d: unknown variable \"%s\"%s\n"),
Packit 15a96c
            curenv->scriptname, thisline->lineno, name, "\r");
Packit 15a96c
    exit(1);
Packit 15a96c
  }
Packit 15a96c
  if ((v = (struct var *)malloc(sizeof(struct var))) == NULL ||
Packit 15a96c
      (v->name = strsave(name)) == NULL) {
Packit 15a96c
    fprintf(stderr, _("script \"%s\": out of memory%s\n"),
Packit 15a96c
            curenv->scriptname, "\r");
Packit 15a96c
    exit(1);
Packit 15a96c
  }
Packit 15a96c
  if (end)
Packit 15a96c
    end->next = v;
Packit 15a96c
  else
Packit 15a96c
    curenv->vars = v;
Packit 15a96c
  v->next = NULL;
Packit 15a96c
  v->value = 0;
Packit 15a96c
  return v;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Read a number or variable.
Packit 15a96c
 */
Packit 15a96c
int getnum(char *text)
Packit 15a96c
{
Packit 15a96c
  int val;
Packit 15a96c
Packit 15a96c
  if (!strcmp(text, "$?"))
Packit 15a96c
    return laststatus;
Packit 15a96c
  if ((val = atoi(text)) != 0 || *text == '0')
Packit 15a96c
    return val;
Packit 15a96c
  return getvar(text, 0)->value;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Get the lines following "expect" into memory.
Packit 15a96c
 */
Packit 15a96c
struct line **buildexpect(void)
Packit 15a96c
{
Packit 15a96c
  static struct line *seq[17];
Packit 15a96c
  int f;
Packit 15a96c
  char *w, *t;
Packit 15a96c
Packit 15a96c
  for(f = 0; f < 16; f++) {
Packit 15a96c
    if (thisline == NULL) {
Packit 15a96c
      fprintf(stderr, _("script \"%s\": unexpected end of file%s\n"),
Packit 15a96c
              curenv->scriptname, "\r");
Packit 15a96c
      exit(1);
Packit 15a96c
    }
Packit 15a96c
    t = thisline->line;
Packit 15a96c
    w = getword(&t);
Packit 15a96c
    if (!strcmp(w, "}")) {
Packit 15a96c
      if (*t)
Packit 15a96c
        syntaxerr(_("(garbage after })"));
Packit 15a96c
      seq[f] = NULL;
Packit 15a96c
      return seq;
Packit 15a96c
    }
Packit 15a96c
    seq[f] = thisline;
Packit 15a96c
    thisline = thisline->next;
Packit 15a96c
  }
Packit 15a96c
  if (f == 16)
Packit 15a96c
    syntaxerr(_("(too many arguments)"));
Packit 15a96c
  return seq;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Our "expect" function.
Packit 15a96c
 */
Packit 15a96c
int expect(char *text)
Packit 15a96c
{
Packit 15a96c
  char *s, *w;
Packit 15a96c
  struct line **volatile seq;
Packit 15a96c
  struct line oneline;
Packit 15a96c
  struct line *dflseq[2];
Packit 15a96c
  char *volatile toact = "exit 1";
Packit 15a96c
  volatile int found = 0;
Packit 15a96c
  int f, val, c;
Packit 15a96c
  char *action = NULL;
Packit 15a96c
Packit 15a96c
  if (inexpect) {
Packit 15a96c
    fprintf(stderr, _("script \"%s\" line %d: nested expect%s\n"),
Packit 15a96c
            curenv->scriptname, thisline->lineno, "\r");
Packit 15a96c
    exit(1);
Packit 15a96c
  }
Packit 15a96c
  etimeout = 120;
Packit 15a96c
  inexpect = 1;
Packit 15a96c
Packit 15a96c
  s = getword(&text);
Packit 15a96c
  if (!strcmp(s, "{")) {
Packit 15a96c
    if (*text)
Packit 15a96c
      syntaxerr(_("(garbage after {)"));
Packit 15a96c
    thisline = thisline->next;
Packit 15a96c
    seq = buildexpect();
Packit 15a96c
  } else {
Packit 15a96c
    oneline.line = s;
Packit 15a96c
    oneline.next = NULL;
Packit 15a96c
    dflseq[0] = &oneline;
Packit 15a96c
    dflseq[1] = NULL;
Packit 15a96c
    seq = dflseq;
Packit 15a96c
  }
Packit 15a96c
  /* Seek a timeout command */
Packit 15a96c
  for (f = 0; seq[f]; f++) {
Packit 15a96c
    if (!strncmp(seq[f]->line, "timeout", 7)) {
Packit 15a96c
      c = seq[f]->line[7];
Packit 15a96c
      if (c == 0 || (c != ' ' && c != '\t'))
Packit 15a96c
        continue;
Packit 15a96c
      s = seq[f]->line + 7;
Packit 15a96c
      /* seq[f] = NULL; */
Packit 15a96c
      skipspace(&s);
Packit 15a96c
      w = getword(&s);
Packit 15a96c
      if (w == NULL)
Packit 15a96c
        syntaxerr(_("(argument expected)"));
Packit 15a96c
      val = getnum(w);
Packit 15a96c
      if (val == 0)
Packit 15a96c
        syntaxerr(_("(invalid argument)"));
Packit 15a96c
      etimeout = val;
Packit 15a96c
      skipspace(&s);
Packit 15a96c
      if (*s != 0)
Packit 15a96c
        toact = s;
Packit 15a96c
      break;
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
  if (sigsetjmp(ejmp, 1) != 0) {
Packit 15a96c
    f = s_exec(toact);
Packit 15a96c
    inexpect = 0;
Packit 15a96c
    return f;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  /* Allright. Now do the expect. */
Packit 15a96c
  c = OK;
Packit 15a96c
  while (!found) {
Packit 15a96c
    action = NULL;
Packit 15a96c
    readchar();
Packit 15a96c
    for (f = 0; seq[f]; f++) {
Packit 15a96c
      s = seq[f]->line;
Packit 15a96c
      w = getword(&s);
Packit 15a96c
      if (expfound(w)) {
Packit 15a96c
        action = s;
Packit 15a96c
        found = 1;
Packit 15a96c
        break;
Packit 15a96c
      }
Packit 15a96c
    }
Packit 15a96c
    if (action != NULL && *action) {
Packit 15a96c
      found = 0;
Packit 15a96c
      /* Maybe BREAK or RETURN */
Packit 15a96c
      if ((c = s_exec(action)) != OK)
Packit 15a96c
        found = 1;
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
  inexpect = 0;
Packit 15a96c
  etimeout = 0;
Packit 15a96c
  return c;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Jump to a shell and run a command.
Packit 15a96c
 */
Packit 15a96c
int shell(char *text)
Packit 15a96c
{
Packit 15a96c
  laststatus = system(text);
Packit 15a96c
  return OK;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Run a command and send its stdout to stdout ( = modem).
Packit 15a96c
 */
Packit 15a96c
int pipedshell(char *text)
Packit 15a96c
{
Packit 15a96c
  FILE *fp = popen(text, "r");
Packit 15a96c
  if (fp == NULL) {
Packit 15a96c
    laststatus = errno;
Packit 15a96c
    return OK;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  char received[64];
Packit 15a96c
  size_t read = 0;
Packit 15a96c
  while ((read = fread(received, sizeof(char), 64, fp))) {
Packit 15a96c
#ifdef HAVE_USLEEP
Packit 15a96c
    /* 200 ms delay. */
Packit 15a96c
    usleep(200000);
Packit 15a96c
#endif
Packit 15a96c
Packit 15a96c
    char *sent = received;
Packit 15a96c
    while (read-- > 0)
Packit 15a96c
      fputc(*sent++, stdout);
Packit 15a96c
Packit 15a96c
    fflush(stdout);
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  int status = pclose(fp);
Packit 15a96c
  if (WIFEXITED(status))
Packit 15a96c
    laststatus = WEXITSTATUS(status);
Packit 15a96c
  else if (WIFSIGNALED(status))
Packit 15a96c
    laststatus = WTERMSIG(status);
Packit 15a96c
  else
Packit 15a96c
    laststatus = status;
Packit 15a96c
  return OK;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Send output to stdout ( = modem)
Packit 15a96c
 */
Packit 15a96c
int dosend(char *text)
Packit 15a96c
{
Packit 15a96c
#ifdef HAVE_USLEEP
Packit 15a96c
  /* 200 ms delay. */
Packit 15a96c
  usleep(200000);
Packit 15a96c
#endif
Packit 15a96c
Packit 15a96c
  /* Before we send anything, flush input buffer. */
Packit 15a96c
  m_flush(0);
Packit 15a96c
  memset(inbuf, 0, sizeof(inbuf));
Packit 15a96c
Packit 15a96c
  newline = "\r";
Packit 15a96c
  return output(text, stdout);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Exit from the script, possibly with a value.
Packit 15a96c
 */
Packit 15a96c
int doexit(char *text)
Packit 15a96c
{
Packit 15a96c
  char *w;
Packit 15a96c
  int ret = 0;
Packit 15a96c
Packit 15a96c
  w = getword(&text);
Packit 15a96c
  if (w != NULL)
Packit 15a96c
    ret = getnum(w);
Packit 15a96c
  curenv->exstat = ret;
Packit 15a96c
  longjmp(curenv->ebuf, 1);
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Goto a specific label.
Packit 15a96c
 */
Packit 15a96c
int dogoto(char *text)
Packit 15a96c
{
Packit 15a96c
  char *w;
Packit 15a96c
  struct line *l;
Packit 15a96c
  char buf[32];
Packit 15a96c
  int len;
Packit 15a96c
Packit 15a96c
  w = getword(&text);
Packit 15a96c
  if (w == NULL || *text)
Packit 15a96c
    syntaxerr(_("(in goto/gosub label)"));
Packit 15a96c
  snprintf(buf, sizeof(buf), "%s:", w);
Packit 15a96c
  len = strlen(buf);
Packit 15a96c
  for (l = curenv->lines; l; l = l->next)
Packit 15a96c
    if (!strncmp(l->line, buf, len))
Packit 15a96c
      break;
Packit 15a96c
  if (l == NULL) {
Packit 15a96c
    fprintf(stderr, _("script \"%s\" line %d: label \"%s\" not found%s\n"),
Packit 15a96c
            curenv->scriptname, thisline->lineno, w, "\r");
Packit 15a96c
    exit(1);
Packit 15a96c
  }
Packit 15a96c
  thisline = l;
Packit 15a96c
  /* We return break, to automatically break out of expect loops. */
Packit 15a96c
  return BREAK;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Goto a subroutine.
Packit 15a96c
 */
Packit 15a96c
int dogosub(char *text)
Packit 15a96c
{
Packit 15a96c
  struct line *oldline;
Packit 15a96c
  int ret = OK;
Packit 15a96c
Packit 15a96c
  oldline = thisline;
Packit 15a96c
  dogoto(text);
Packit 15a96c
Packit 15a96c
  while (ret != ERR) {
Packit 15a96c
    if ((thisline = thisline->next) == NULL) {
Packit 15a96c
      fprintf(stderr, _("script \"%s\": no return from gosub%s\n"),
Packit 15a96c
              curenv->scriptname, "\r");
Packit 15a96c
      exit(1);
Packit 15a96c
    }
Packit 15a96c
    ret = s_exec(thisline->line);
Packit 15a96c
    if (ret == RETURN) {
Packit 15a96c
      ret = OK;
Packit 15a96c
      thisline = oldline;
Packit 15a96c
      break;
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
  return ret;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Return from a subroutine.
Packit 15a96c
 */
Packit 15a96c
int doreturn(char *text)
Packit 15a96c
{
Packit 15a96c
  (void)text;
Packit 15a96c
  return RETURN;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Print text to stderr.
Packit 15a96c
 */
Packit 15a96c
int print(char *text)
Packit 15a96c
{
Packit 15a96c
  newline = "\r\n";
Packit 15a96c
Packit 15a96c
  return output(text, stderr);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Declare a variable (integer)
Packit 15a96c
 */
Packit 15a96c
int doset(char *text)
Packit 15a96c
{
Packit 15a96c
  char *w;
Packit 15a96c
  struct var *v;
Packit 15a96c
Packit 15a96c
  w = getword(&text);
Packit 15a96c
  if (w == NULL)
Packit 15a96c
    syntaxerr(_("(missing var name)"));
Packit 15a96c
  v = getvar(w, 1);
Packit 15a96c
  if (*text)
Packit 15a96c
    v->value = getnum(getword(&text));
Packit 15a96c
  return OK;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Lower the value of a variable.
Packit 15a96c
 */
Packit 15a96c
int dodec(char *text)
Packit 15a96c
{
Packit 15a96c
  char *w;
Packit 15a96c
  struct var *v;
Packit 15a96c
Packit 15a96c
  w = getword(&text);
Packit 15a96c
  if (w == NULL)
Packit 15a96c
    syntaxerr(_("(expected variable)"));
Packit 15a96c
  v = getvar(w, 0);
Packit 15a96c
  v->value--;
Packit 15a96c
  return OK;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Increase the value of a variable.
Packit 15a96c
 */
Packit 15a96c
int doinc(char *text)
Packit 15a96c
{
Packit 15a96c
  char *w;
Packit 15a96c
  struct var *v;
Packit 15a96c
Packit 15a96c
  w = getword(&text);
Packit 15a96c
  if (w == NULL)
Packit 15a96c
    syntaxerr(_("(expected variable)"));
Packit 15a96c
  v = getvar(w, 0);
Packit 15a96c
  v->value++;
Packit 15a96c
  return OK;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * If syntax: if n1 [><=] n2 command.
Packit 15a96c
 */
Packit 15a96c
int doif(char *text)
Packit 15a96c
{
Packit 15a96c
  char *w;
Packit 15a96c
  int n1;
Packit 15a96c
  int n2;
Packit 15a96c
  char op;
Packit 15a96c
Packit 15a96c
  if ((w = getword(&text)) == NULL)
Packit 15a96c
    syntaxerr("(if)");
Packit 15a96c
  n1 = getnum(w);
Packit 15a96c
  if ((w = getword(&text)) == NULL)
Packit 15a96c
    syntaxerr("(if)");
Packit 15a96c
  if (strcmp(w, "!=") == 0)
Packit 15a96c
    op = '!';
Packit 15a96c
  else {
Packit 15a96c
    if (*w == 0 || w[1] != 0)
Packit 15a96c
      syntaxerr("(if)");
Packit 15a96c
    op = *w;
Packit 15a96c
  }
Packit 15a96c
  if ((w = getword(&text)) == NULL)
Packit 15a96c
    syntaxerr("(if)");
Packit 15a96c
  n2 = getnum(w);
Packit 15a96c
  if (!*text)
Packit 15a96c
    syntaxerr(_("(expected command after if)"));
Packit 15a96c
Packit 15a96c
  if (op == '=') {
Packit 15a96c
    if (n1 != n2)
Packit 15a96c
      return OK;
Packit 15a96c
  } else if (op == '!') {
Packit 15a96c
    if (n1 == n2)
Packit 15a96c
      return OK;
Packit 15a96c
  } else if (op == '>') {
Packit 15a96c
    if (n1 <= n2)
Packit 15a96c
      return OK;
Packit 15a96c
  } else if (op == '<') {
Packit 15a96c
    if (n1 >= n2)
Packit 15a96c
      return OK;
Packit 15a96c
  } else
Packit 15a96c
    syntaxerr(_("(unknown operator)"));
Packit 15a96c
Packit 15a96c
  return s_exec(text);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Set the global timeout-time.
Packit 15a96c
 */
Packit 15a96c
int dotimeout(char *text)
Packit 15a96c
{
Packit 15a96c
  char *w;
Packit 15a96c
  int val;
Packit 15a96c
Packit 15a96c
  w = getword(&text);
Packit 15a96c
  if (w == NULL)
Packit 15a96c
    syntaxerr(_("(argument expected)"));
Packit 15a96c
  if ((val = getnum(w)) == 0)
Packit 15a96c
    syntaxerr(_("(invalid argument)"));
Packit 15a96c
  gtimeout = val;
Packit 15a96c
  return OK;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Turn verbose on/off (= echo stdin to stderr)
Packit 15a96c
 */
Packit 15a96c
int doverbose(char *text)
Packit 15a96c
{
Packit 15a96c
  char *w;
Packit 15a96c
Packit 15a96c
  curenv->verbose = 1;
Packit 15a96c
Packit 15a96c
  if ((w = getword(&text)) != NULL) {
Packit 15a96c
    if (!strcmp(w, "on"))
Packit 15a96c
      return OK;
Packit 15a96c
    if (!strcmp(w, "off")) {
Packit 15a96c
      curenv->verbose = 0;
Packit 15a96c
      return OK;
Packit 15a96c
    }
Packit 15a96c
  }
Packit 15a96c
  syntaxerr(_("(unexpected argument)"));
Packit 15a96c
  return ERR;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Sleep for a certain number of seconds.
Packit 15a96c
 */
Packit 15a96c
int dosleep(char *text)
Packit 15a96c
{
Packit 15a96c
  int foo, tm;
Packit 15a96c
Packit 15a96c
  tm = getnum(text);
Packit 15a96c
  foo = gtimeout - tm;
Packit 15a96c
Packit 15a96c
  /* The alarm goes off every second.. */
Packit 15a96c
  while (gtimeout != foo)
Packit 15a96c
    pause();
Packit 15a96c
  return OK;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Break out of an expect loop.
Packit 15a96c
 */
Packit 15a96c
int dobreak(char *dummy)
Packit 15a96c
{
Packit 15a96c
  (void)dummy;
Packit 15a96c
  if (!inexpect) {
Packit 15a96c
    fprintf(stderr, _("script \"%s\" line %d: break outside of expect%s\n"),
Packit 15a96c
            curenv->scriptname, thisline->lineno, "\r");
Packit 15a96c
    exit(1);
Packit 15a96c
  }
Packit 15a96c
  return BREAK;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Call another script!
Packit 15a96c
 */
Packit 15a96c
int docall(char *text)
Packit 15a96c
{
Packit 15a96c
  struct line *oldline;
Packit 15a96c
  struct env *oldenv;
Packit 15a96c
  int er;
Packit 15a96c
Packit 15a96c
  if (*text == 0)
Packit 15a96c
    syntaxerr(_("(argument expected)"));
Packit 15a96c
Packit 15a96c
  if (inexpect) {
Packit 15a96c
    fprintf(stderr, _("script \"%s\" line %d: call inside expect%s\n"),
Packit 15a96c
            curenv->scriptname, thisline->lineno, "\r");
Packit 15a96c
    exit(1);
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  oldline = thisline;
Packit 15a96c
  oldenv = curenv;
Packit 15a96c
  if ((er = execscript(text)) != 0)
Packit 15a96c
    exit(er);
Packit 15a96c
  /* freemem(); */
Packit 15a96c
  thisline = oldline;
Packit 15a96c
  curenv = oldenv;
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
static int do_log_wrapper(char *s)
Packit 15a96c
{
Packit 15a96c
  do_log("%s", s);
Packit 15a96c
  return 0;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/* KEYWORDS */
Packit 15a96c
struct kw {
Packit 15a96c
  const char *command;
Packit 15a96c
  int (*fn)(char *);
Packit 15a96c
} keywords[] = {
Packit 15a96c
  { "expect",	expect },
Packit 15a96c
  { "send",	dosend },
Packit 15a96c
  { "!<",	pipedshell },
Packit 15a96c
  { "!",	shell },
Packit 15a96c
  { "goto",	dogoto },
Packit 15a96c
  { "gosub",	dogosub },
Packit 15a96c
  { "return",	doreturn },
Packit 15a96c
  { "exit",	doexit },
Packit 15a96c
  { "print",	print },
Packit 15a96c
  { "set",	doset },
Packit 15a96c
  { "inc",	doinc },
Packit 15a96c
  { "dec",	dodec },
Packit 15a96c
  { "if",	doif },
Packit 15a96c
  { "timeout",	dotimeout },
Packit 15a96c
  { "verbose",	doverbose },
Packit 15a96c
  { "sleep",	dosleep },
Packit 15a96c
  { "break",	dobreak },
Packit 15a96c
  { "call",	docall },
Packit 15a96c
  { "log",	do_log_wrapper },
Packit 15a96c
  { NULL,	(int(*)(char *))0 }
Packit 15a96c
};
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Execute one line.
Packit 15a96c
 */
Packit 15a96c
int s_exec(char *text)
Packit 15a96c
{
Packit 15a96c
  char *w;
Packit 15a96c
  struct kw *k;
Packit 15a96c
Packit 15a96c
  w = getword(&text);
Packit 15a96c
Packit 15a96c
  /* If it is a label or a comment, skip it. */
Packit 15a96c
  if (w == NULL || *w == '#' || w[strlen(w) - 1] == ':')
Packit 15a96c
    return OK;
Packit 15a96c
Packit 15a96c
  /* See which command it is. */
Packit 15a96c
  for (k = keywords; k->command; k++)
Packit 15a96c
    if (!strcmp(w, k->command))
Packit 15a96c
      break;
Packit 15a96c
Packit 15a96c
  /* Command not found? */
Packit 15a96c
  if (k->command == NULL) {
Packit 15a96c
    fprintf(stderr, _("script \"%s\" line %d: unknown command \"%s\"%s\n"),
Packit 15a96c
            curenv->scriptname, thisline->lineno, w, "\r");
Packit 15a96c
    exit(1);
Packit 15a96c
  }
Packit 15a96c
  return (*(k->fn))(text);
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
/*
Packit 15a96c
 * Run the script by continously executing "thisline".
Packit 15a96c
 */
Packit 15a96c
int execscript(const char *s)
Packit 15a96c
{
Packit 15a96c
  volatile int ret = OK;
Packit 15a96c
Packit 15a96c
  curenv = (struct env *)malloc(sizeof(struct env));
Packit 15a96c
  curenv->lines = NULL;
Packit 15a96c
  curenv->vars  = NULL;
Packit 15a96c
  curenv->verbose = 1;
Packit 15a96c
  curenv->scriptname = s;
Packit 15a96c
Packit 15a96c
  if (readscript(s) < 0) {
Packit 15a96c
    freemem();
Packit 15a96c
    free(curenv);
Packit 15a96c
    return ERR;
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  signal(SIGALRM, myclock);
Packit 15a96c
  alarm(1);
Packit 15a96c
  if (setjmp(curenv->ebuf) == 0) {
Packit 15a96c
    thisline = curenv->lines;
Packit 15a96c
    while (thisline != NULL && (ret = s_exec(thisline->line)) != ERR)
Packit 15a96c
      thisline = thisline->next;
Packit 15a96c
  } else
Packit 15a96c
    ret = curenv->exstat ? ERR : 0;
Packit 15a96c
  free(curenv);
Packit 15a96c
  return ret;
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
void do_args(int argc, char **argv)
Packit 15a96c
{
Packit 15a96c
  if (argc > 1 && !strcmp(argv[1], "--version")) {
Packit 15a96c
    printf(_("runscript, part of minicom version %s\n"), VERSION);
Packit 15a96c
    exit(0);
Packit 15a96c
  }
Packit 15a96c
Packit 15a96c
  if (argc < 2) {
Packit 15a96c
    fprintf(stderr, _("Usage: runscript <scriptfile> [logfile [homedir]]%s\n"),"\r");
Packit 15a96c
    exit(1);
Packit 15a96c
  }
Packit 15a96c
}
Packit 15a96c
Packit 15a96c
int main(int argc, char **argv)
Packit 15a96c
{
Packit 15a96c
  char *s;
Packit 15a96c
#if 0 /* Shouldn't need this.. */
Packit 15a96c
  signal(SIGHUP, SIG_IGN);
Packit 15a96c
#endif
Packit 15a96c
Packit 15a96c
  /* initialize locale support */
Packit 15a96c
  setlocale(LC_ALL, "");
Packit 15a96c
  bindtextdomain(PACKAGE, LOCALEDIR);
Packit 15a96c
  textdomain(PACKAGE);
Packit 15a96c
Packit 15a96c
  init_env();
Packit 15a96c
Packit 15a96c
  do_args(argc, argv);
Packit 15a96c
Packit 15a96c
  memset(inbuf, 0, sizeof(inbuf));
Packit 15a96c
Packit 15a96c
  if (argc > 2) {
Packit 15a96c
    strncpy(logfname, argv[2], sizeof(logfname));
rpm-build c8e99c
    logfname[sizeof(logfname) - 1] = '\0';
Packit 15a96c
    if (argc > 3)
Packit 15a96c
      strncpy(homedir, argv[3], sizeof(homedir));
Packit 15a96c
    else if ((s = getenv("HOME")) != NULL)
Packit 15a96c
      strncpy(homedir, s, sizeof(homedir));
Packit 15a96c
    else
Packit 15a96c
      homedir[0] = 0;
rpm-build c8e99c
    homedir[sizeof(homedir) - 1] = '\0';
Packit 15a96c
  }
Packit 15a96c
  else
Packit 15a96c
    logfname[0] = 0;
Packit 15a96c
Packit 15a96c
  return execscript(argv[1]) != OK;
Packit 15a96c
}