Exemplo n.º 1
0
static xiosingle_t *xioparse_single(const char **addr) {
    xiofile_t *xfd;
    xiosingle_t *sfd;
    struct addrname *ae;
    const struct addrdesc *addrdesc = NULL;
    const char *ends[4+1];
    const char *hquotes[] = {
        "'",
        NULL
    } ;
    const char *squotes[] = {
        "\"",
        NULL
    } ;
    const char *nests[] = {
        "'", "'",
        "(", ")",
        "[", "]",
        "{", "}",
        NULL
    } ;
    char token[512], *tokp;
    size_t len;
    int i;

    /* init */
    i = 0;
    /*ends[i++] = xioopts.chainsep;*/	/* default: "|" */
    ends[i++] = xioopts.pipesep;		/* default: "!!" */
    ends[i++] = ","/*xioopts.comma*/;		/* default: "," */
    ends[i++] = ":"/*xioopts.colon*/;		/* default: ":" */
    ends[i++] = NULL;

    if ((xfd = xioallocfd()) == NULL) {
        return NULL;
    }
    sfd = &xfd->stream;
    sfd->argc = 0;

    len = sizeof(token);
    tokp = token;
    if (nestlex(addr, &tokp, &len, ends, hquotes, squotes, nests,
                true, true, false) < 0) {
        Error2("keyword too long, in address \"%s%s\"", token, *addr);
    }
    *tokp = '\0';  /*! len? */
    ae = (struct addrname *)
         keyw((struct wordent *)&addressnames, token,
              sizeof(addressnames)/sizeof(struct addrname)-1);

    if (ae) {
        addrdesc = ae->desc;
        /* keyword */
        if ((sfd->argv[sfd->argc++] = strdup(token)) == NULL) {
            Error1("strdup(\"%s\"): out of memory", token);
        }
    } else {
        if (false) {
            ;
#if WITH_FDNUM
        } else if (isdigit(token[0]&0xff) && token[1] == '\0') {
            Info1("interpreting address \"%s\" as file descriptor", token);
            addrdesc = &addr_fd;
            if ((sfd->argv[sfd->argc++] = strdup("FD")) == NULL) {
                Error("strdup(\"FD\"): out of memory");
            }
            if ((sfd->argv[sfd->argc++] = strdup(token)) == NULL) {
                Error1("strdup(\"%s\"): out of memory", token);
            }
            /*! check argc overflow */
#endif /* WITH_FDNUM */
#if WITH_GOPEN
        } else if (strchr(token, '/')) {
            Info1("interpreting address \"%s\" as file name", token);
            addrdesc = &addr_gopen;
            if ((sfd->argv[sfd->argc++] = strdup("GOPEN")) == NULL) {
                Error("strdup(\"GOPEN\"): out of memory");
            }
            if ((sfd->argv[sfd->argc++] = strdup(token)) == NULL) {
                Error1("strdup(\"%s\"): out of memory", token);
            }
            /*! check argc overflow */
#endif /* WITH_GOPEN */
        } else {
            Error1("unknown device/address \"%s\"", token);
            /*!!! free something*/ return NULL;
        }
    }

    sfd->tag  = XIO_TAG_RDWR;
    sfd->addr = addrdesc;

    while (!strncmp(*addr, xioopts.paramsep, strlen(xioopts.paramsep))) {
        *addr += strlen(xioopts.paramsep);
        len = sizeof(token);
        tokp = token;
        if (nestlex(addr, &tokp, &len, ends, hquotes, squotes, nests,
                    true, true, false) != 0) {
            Error2("syntax error in address \"%s%s\"", token, *addr);
        }
        *tokp = '\0';
        if ((sfd->argv[sfd->argc++] = strdup(token)) == NULL) {
            Error1("strdup(\"%s\"): out of memory", token);
        }
    }

    if (parseopts(addr, addrdesc->groups, &sfd->opts) < 0) {
        free(xfd);
        return NULL;
    }

    return sfd;
}
Exemplo n.º 2
0
static int xioopen_exec(int argc, const char *argv[], struct opt *opts,
		int xioflags,	/* XIO_RDONLY, XIO_MAYCHILD etc. */
		xiofile_t *fd,
		unsigned groups,
		int dummy1, int dummy2, int dummy3
		) {
   int status;
   bool dash = false;
   int duptostderr;

   if (argc != 2) {
      Error3("\"%s:%s\": wrong number of parameters (%d instead of 1)", argv[0], argv[1], argc-1);
   }
      
   retropt_bool(opts, OPT_DASH, &dash);

   status = _xioopen_foxec(xioflags, &fd->stream, groups, &opts, &duptostderr);
   if (status < 0)  return status;
   if (status == 0) {	/* child */
      const char *ends[] = { " ", NULL };
      const char *hquotes[] = { "'", NULL };
      const char *squotes[] = { "\"", NULL };
      const char *nests[] = {
	 "'", "'",
	 "(", ")",
	 "[", "]",
	 "{", "}",
	 NULL
      } ;
      char **pargv = NULL;
      int pargc;
      size_t len;
      const char *strp;
      char *token; /*! */
      char *tokp;
      char *path = NULL;
      char *tmp;
      int numleft;

      /*! Close(something) */
      /* parse command line */
      Debug1("child: args = \"%s\"", argv[1]);
      pargv = Malloc(8*sizeof(char *));
      if (pargv == NULL)  return STAT_RETRYLATER;
      len = strlen(argv[1])+1;
      strp = argv[1];
      token = Malloc(len); /*! */
      tokp = token;
      if (nestlex(&strp, &tokp, &len, ends, hquotes, squotes, nests,
		  true, true, false) < 0) {
	 Error("internal: miscalculated string lengths");
      }
      *tokp++ = '\0';
      pargv[0] = strrchr(tokp-1, '/');
      if (pargv[0] == NULL)  pargv[0] = token;  else  ++pargv[0];
      pargc = 1;
      while (*strp == ' ') {
	 while (*++strp == ' ')  ;
	 if ((pargc & 0x07) == 0) {
	    pargv = Realloc(pargv, (pargc+8)*sizeof(char *));
	    if (pargv == NULL)  return STAT_RETRYLATER;
	 }
	 pargv[pargc++] = tokp;
	 if (nestlex(&strp, &tokp, &len, ends, hquotes, squotes, nests,
		     true, true, false) < 0) {
	    Error("internal: miscalculated string lengths");
	 }
	 *tokp++ = '\0';
      }
      pargv[pargc] = NULL;

      if ((tmp = Malloc(strlen(pargv[0])+2)) == NULL) {
	 return STAT_RETRYLATER;
      }
      if (dash) {
	 tmp[0] = '-';
	 strcpy(tmp+1, pargv[0]);
      } else {
	 strcpy(tmp, pargv[0]);
      }
      pargv[0] = tmp;

      if (setopt_path(opts, &path) < 0) {
	 /* this could be dangerous, so let us abort this child... */
	 Exit(1);
      }

      if ((numleft = leftopts(opts)) > 0) {
	 Error1("%d option(s) could not be used", numleft);
	 showleft(opts);
	 return STAT_NORETRY;
      }

      /* only now redirect stderr */
      if (duptostderr >= 0) {
	 diag_dup();
	 Dup2(duptostderr, 2);
      }
      Notice1("execvp'ing \"%s\"", token);
      Execvp(token, pargv);
      /* here we come only if execvp() failed */
      switch (pargc) {
      case 1: Error3("execvp(\"%s\", \"%s\"): %s", token, pargv[0], strerror(errno)); break; 
      case 2: Error4("execvp(\"%s\", \"%s\", \"%s\"): %s", token, pargv[0], pargv[1], strerror(errno)); break; 
      case 3:
      default:
	 Error5("execvp(\"%s\", \"%s\", \"%s\", \"%s\", ...): %s", token, pargv[0], pargv[1], pargv[2], strerror(errno)); break; 
      }
      Exit(1);	/* this child process */
   }

   /* parent */
   return 0;
}