195023Ssuz/*
278064Sume * FreeBSD install - a package for the installation and maintenance
3139823Simp * of non-core utilities.
454263Sshin *
554263Sshin * Redistribution and use in source and binary forms, with or without
654263Sshin * modification, are permitted provided that the following conditions
754263Sshin * are met:
854263Sshin * 1. Redistributions of source code must retain the above copyright
954263Sshin *    notice, this list of conditions and the following disclaimer.
1054263Sshin * 2. Redistributions in binary form must reproduce the above copyright
1154263Sshin *    notice, this list of conditions and the following disclaimer in the
1254263Sshin *    documentation and/or other materials provided with the distribution.
1354263Sshin *
1454263Sshin * Jordan K. Hubbard
1554263Sshin * 18 July 1993
1654263Sshin *
1754263Sshin * Miscellaneous system routines.
1854263Sshin *
1954263Sshin */
2054263Sshin
2154263Sshin#include <sys/cdefs.h>
2254263Sshin__FBSDID("$FreeBSD$");
2354263Sshin
2454263Sshin#include "lib.h"
2554263Sshin#include <err.h>
2654263Sshin
2754263Sshin/*
2854263Sshin * Unusual system() substitute.  Accepts format string and args,
2954263Sshin * builds and executes command.  Returns exit code.
3054263Sshin */
3154263Sshin
3254263Sshinint
3354263Sshinvsystem(const char *fmt, ...)
3454263Sshin{
3554263Sshin    va_list args;
3654263Sshin    char *cmd;
3754263Sshin    long maxargs;
3854263Sshin    int ret;
3954263Sshin
4054263Sshin    maxargs = sysconf(_SC_ARG_MAX);
4154263Sshin    maxargs -= 32;			/* some slop for the sh -c */
4278064Sume    cmd = malloc(maxargs);
4378064Sume    if (!cmd) {
4454263Sshin	warnx("vsystem can't alloc arg space");
4554263Sshin	return 1;
4654263Sshin    }
4754263Sshin
4854263Sshin    va_start(args, fmt);
49129880Sphk    if (vsnprintf(cmd, maxargs, fmt, args) > maxargs) {
5054263Sshin	warnx("vsystem args are too long");
5178064Sume	va_end(args);
5254263Sshin	return 1;
5378064Sume    }
5478064Sume#ifdef DEBUG
5583934Sbrooksprintf("Executing %s\n", cmd);
5683934Sbrooks#endif
57181803Sbz    ret = system(cmd);
5854263Sshin    va_end(args);
5954263Sshin    free(cmd);
60130933Sbrooks    return ret;
6154263Sshin}
6254263Sshin
6354263Sshinchar *
6454263Sshinvpipe(const char *fmt, ...)
6554263Sshin{
6678064Sume   FILE *fp;
6778064Sume   char *cmd, *rp;
6878064Sume   long maxargs;
6978064Sume   va_list args;
7078064Sume
7178064Sume    rp = malloc(MAXPATHLEN);
7278064Sume    if (!rp) {
7378064Sume	warnx("vpipe can't alloc buffer space");
7478064Sume	return NULL;
7578064Sume    }
7678064Sume    maxargs = sysconf(_SC_ARG_MAX);
7778064Sume    maxargs -= 32;			    /* some slop for the sh -c */
7878064Sume    cmd = alloca(maxargs);
7978064Sume    if (!cmd) {
80185571Sbz	warnx("vpipe can't alloc arg space");
8178064Sume	return NULL;
8278064Sume    }
8383934Sbrooks
8483934Sbrooks    va_start(args, fmt);
8583934Sbrooks    if (vsnprintf(cmd, maxargs, fmt, args) > maxargs) {
86147256Sbrooks	warnx("vsystem args are too long");
8783934Sbrooks	va_end(args);
8883934Sbrooks	return NULL;
8992725Salfred    }
9092725Salfred#ifdef DEBUG
91191148Skmacy    fprintf(stderr, "Executing %s\n", cmd);
9292725Salfred#endif
9391317Sdillon    fflush(NULL);
9492725Salfred    fp = popen(cmd, "r");
9591317Sdillon    if (fp == NULL) {
9654263Sshin	warnx("popen() failed");
9792725Salfred	va_end(args);
9878064Sume	return NULL;
9983934Sbrooks    }
10054263Sshin    get_string(rp, MAXPATHLEN, fp);
101160195Ssam#ifdef DEBUG
102128209Sbrooks    fprintf(stderr, "Returned %s\n", rp);
10383934Sbrooks#endif
104130933Sbrooks    va_end(args);
10583934Sbrooks    if (pclose(fp) || (strlen(rp) == 0)) {
10654263Sshin	free(rp);
10754263Sshin	return NULL;
10883934Sbrooks    }
10983934Sbrooks    return rp;
11083934Sbrooks}
11183934Sbrooks