1/*
2 * FreeBSD install - a package for the installation and maintenance
3 * of non-core utilities.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * Jordan K. Hubbard
15 * 18 July 1993
16 *
17 * Miscellaneous system routines.
18 *
19 */
20
21#include <sys/cdefs.h>
22__FBSDID("$FreeBSD: releng/10.3/usr.sbin/pkg_install/lib/exec.c 252363 2013-06-29 00:37:49Z obrien $");
23
24#include "lib.h"
25#include <err.h>
26
27/*
28 * Unusual system() substitute.  Accepts format string and args,
29 * builds and executes command.  Returns exit code.
30 */
31
32int
33vsystem(const char *fmt, ...)
34{
35    va_list args;
36    char *cmd;
37    long maxargs;
38    int ret;
39
40    maxargs = sysconf(_SC_ARG_MAX);
41    maxargs -= 32;			/* some slop for the sh -c */
42    cmd = malloc(maxargs);
43    if (!cmd) {
44	warnx("vsystem can't alloc arg space");
45	return 1;
46    }
47
48    va_start(args, fmt);
49    if (vsnprintf(cmd, maxargs, fmt, args) > maxargs) {
50	warnx("vsystem args are too long");
51	va_end(args);
52	return 1;
53    }
54#ifdef DEBUG
55printf("Executing %s\n", cmd);
56#endif
57    ret = system(cmd);
58    va_end(args);
59    free(cmd);
60    return ret;
61}
62
63char *
64vpipe(const char *fmt, ...)
65{
66   FILE *fp;
67   char *cmd, *rp;
68   long maxargs;
69   va_list args;
70
71    rp = malloc(MAXPATHLEN);
72    if (!rp) {
73	warnx("vpipe can't alloc buffer space");
74	return NULL;
75    }
76    maxargs = sysconf(_SC_ARG_MAX);
77    maxargs -= 32;			    /* some slop for the sh -c */
78    cmd = alloca(maxargs);
79    if (!cmd) {
80	warnx("vpipe can't alloc arg space");
81	return NULL;
82    }
83
84    va_start(args, fmt);
85    if (vsnprintf(cmd, maxargs, fmt, args) > maxargs) {
86	warnx("vsystem args are too long");
87	va_end(args);
88	return NULL;
89    }
90#ifdef DEBUG
91    fprintf(stderr, "Executing %s\n", cmd);
92#endif
93    fflush(NULL);
94    fp = popen(cmd, "r");
95    if (fp == NULL) {
96	warnx("popen() failed");
97	va_end(args);
98	return NULL;
99    }
100    get_string(rp, MAXPATHLEN, fp);
101#ifdef DEBUG
102    fprintf(stderr, "Returned %s\n", rp);
103#endif
104    va_end(args);
105    if (pclose(fp) || (strlen(rp) == 0)) {
106	free(rp);
107	return NULL;
108    }
109    return rp;
110}
111