1*5c51f124SMoriah Waterland /*
2*5c51f124SMoriah Waterland * CDDL HEADER START
3*5c51f124SMoriah Waterland *
4*5c51f124SMoriah Waterland * The contents of this file are subject to the terms of the
5*5c51f124SMoriah Waterland * Common Development and Distribution License (the "License").
6*5c51f124SMoriah Waterland * You may not use this file except in compliance with the License.
7*5c51f124SMoriah Waterland *
8*5c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing.
10*5c51f124SMoriah Waterland * See the License for the specific language governing permissions
11*5c51f124SMoriah Waterland * and limitations under the License.
12*5c51f124SMoriah Waterland *
13*5c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each
14*5c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the
16*5c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying
17*5c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner]
18*5c51f124SMoriah Waterland *
19*5c51f124SMoriah Waterland * CDDL HEADER END
20*5c51f124SMoriah Waterland */
21*5c51f124SMoriah Waterland
22*5c51f124SMoriah Waterland /*
23*5c51f124SMoriah Waterland * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*5c51f124SMoriah Waterland * Use is subject to license terms.
25*5c51f124SMoriah Waterland */
26*5c51f124SMoriah Waterland
27*5c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28*5c51f124SMoriah Waterland /* All Rights Reserved */
29*5c51f124SMoriah Waterland
30*5c51f124SMoriah Waterland
31*5c51f124SMoriah Waterland #include <stdio.h>
32*5c51f124SMoriah Waterland #include <stdlib.h>
33*5c51f124SMoriah Waterland #include <sys/wait.h>
34*5c51f124SMoriah Waterland #include <unistd.h>
35*5c51f124SMoriah Waterland #include <string.h>
36*5c51f124SMoriah Waterland #include <fcntl.h> /* creat() declaration */
37*5c51f124SMoriah Waterland #include <sys/types.h>
38*5c51f124SMoriah Waterland #include <sys/stat.h>
39*5c51f124SMoriah Waterland #include <pwd.h>
40*5c51f124SMoriah Waterland #include <grp.h>
41*5c51f124SMoriah Waterland #include <locale.h>
42*5c51f124SMoriah Waterland #include <libintl.h>
43*5c51f124SMoriah Waterland #include <pkglib.h>
44*5c51f124SMoriah Waterland #include "install.h"
45*5c51f124SMoriah Waterland #include "libadm.h"
46*5c51f124SMoriah Waterland #include "libinst.h"
47*5c51f124SMoriah Waterland #include "pkginstall.h"
48*5c51f124SMoriah Waterland #include "messages.h"
49*5c51f124SMoriah Waterland
50*5c51f124SMoriah Waterland extern char tmpdir[], instdir[];
51*5c51f124SMoriah Waterland extern int pkgverbose;
52*5c51f124SMoriah Waterland
53*5c51f124SMoriah Waterland static int do_exec(int update, char *script, char *output,
54*5c51f124SMoriah Waterland char *inport, char *alt_user);
55*5c51f124SMoriah Waterland static char path[PATH_MAX];
56*5c51f124SMoriah Waterland static char *resppath = NULL;
57*5c51f124SMoriah Waterland static int fd;
58*5c51f124SMoriah Waterland static int respfile_defined = 0;
59*5c51f124SMoriah Waterland static int respfile_ro = 0; /* read only resp file */
60*5c51f124SMoriah Waterland
61*5c51f124SMoriah Waterland /*
62*5c51f124SMoriah Waterland * This informs the calling routine if a read-only response file has been
63*5c51f124SMoriah Waterland * provided on the command line.
64*5c51f124SMoriah Waterland */
65*5c51f124SMoriah Waterland int
rdonly_respfile(void)66*5c51f124SMoriah Waterland rdonly_respfile(void)
67*5c51f124SMoriah Waterland {
68*5c51f124SMoriah Waterland return (respfile_ro);
69*5c51f124SMoriah Waterland }
70*5c51f124SMoriah Waterland
71*5c51f124SMoriah Waterland int
is_a_respfile(void)72*5c51f124SMoriah Waterland is_a_respfile(void)
73*5c51f124SMoriah Waterland {
74*5c51f124SMoriah Waterland return (respfile_defined);
75*5c51f124SMoriah Waterland }
76*5c51f124SMoriah Waterland
77*5c51f124SMoriah Waterland /*
78*5c51f124SMoriah Waterland * This function creates a working copy of the checkinstall script.
79*5c51f124SMoriah Waterland * This is needed in situations where the packages parent directories modes
80*5c51f124SMoriah Waterland * are set too restrictively, i.e. 700.
81*5c51f124SMoriah Waterland *
82*5c51f124SMoriah Waterland * Returns: A pointer to the location of the copied checkinstall
83*5c51f124SMoriah Waterland * script or NULL
84*5c51f124SMoriah Waterland */
85*5c51f124SMoriah Waterland
86*5c51f124SMoriah Waterland char *
dup_chkinstall(char * script)87*5c51f124SMoriah Waterland dup_chkinstall(char *script)
88*5c51f124SMoriah Waterland {
89*5c51f124SMoriah Waterland char *dstpath;
90*5c51f124SMoriah Waterland size_t dstpathLen;
91*5c51f124SMoriah Waterland int r;
92*5c51f124SMoriah Waterland static char *tmpname = "checkinstallXXXXXX";
93*5c51f124SMoriah Waterland
94*5c51f124SMoriah Waterland /* determine length for destination script path */
95*5c51f124SMoriah Waterland
96*5c51f124SMoriah Waterland dstpathLen = strlen(tmpdir) + strlen(tmpname) + 3;
97*5c51f124SMoriah Waterland
98*5c51f124SMoriah Waterland /* allocate storage to hold destination script path */
99*5c51f124SMoriah Waterland
100*5c51f124SMoriah Waterland dstpath = (char *)malloc(dstpathLen);
101*5c51f124SMoriah Waterland if (dstpath == (char *)NULL) {
102*5c51f124SMoriah Waterland return ((char *)NULL);
103*5c51f124SMoriah Waterland }
104*5c51f124SMoriah Waterland
105*5c51f124SMoriah Waterland /* create destination script path */
106*5c51f124SMoriah Waterland
107*5c51f124SMoriah Waterland (void) snprintf(dstpath, dstpathLen, "%s/%s", tmpdir, tmpname);
108*5c51f124SMoriah Waterland
109*5c51f124SMoriah Waterland if (mktemp(dstpath) == NULL) {
110*5c51f124SMoriah Waterland progerr(ERR_TMPFILE_CHK);
111*5c51f124SMoriah Waterland (void) free(dstpath);
112*5c51f124SMoriah Waterland return (NULL);
113*5c51f124SMoriah Waterland }
114*5c51f124SMoriah Waterland
115*5c51f124SMoriah Waterland /* make copy of script */
116*5c51f124SMoriah Waterland
117*5c51f124SMoriah Waterland r = copyf(script, dstpath, (time_t)0);
118*5c51f124SMoriah Waterland if (r != 0) {
119*5c51f124SMoriah Waterland progerr(ERR_CANNOT_COPY, script, dstpath);
120*5c51f124SMoriah Waterland return (NULL);
121*5c51f124SMoriah Waterland }
122*5c51f124SMoriah Waterland
123*5c51f124SMoriah Waterland /* Make the copy of the script readable by all */
124*5c51f124SMoriah Waterland
125*5c51f124SMoriah Waterland if (chmod(dstpath, 0444) != 0) {
126*5c51f124SMoriah Waterland progerr(ERR_CHMOD_CHK);
127*5c51f124SMoriah Waterland (void) free(dstpath);
128*5c51f124SMoriah Waterland return (NULL);
129*5c51f124SMoriah Waterland }
130*5c51f124SMoriah Waterland
131*5c51f124SMoriah Waterland return (dstpath);
132*5c51f124SMoriah Waterland }
133*5c51f124SMoriah Waterland
134*5c51f124SMoriah Waterland /*
135*5c51f124SMoriah Waterland * This function creates a temporary working copy of a read-only response
136*5c51f124SMoriah Waterland * file. It changes the resppath pointer to point to the working copy.
137*5c51f124SMoriah Waterland */
138*5c51f124SMoriah Waterland static int
dup_respfile(void)139*5c51f124SMoriah Waterland dup_respfile(void)
140*5c51f124SMoriah Waterland {
141*5c51f124SMoriah Waterland char tpath[PATH_MAX];
142*5c51f124SMoriah Waterland int r;
143*5c51f124SMoriah Waterland
144*5c51f124SMoriah Waterland (void) strlcpy(tpath, path, sizeof (tpath));
145*5c51f124SMoriah Waterland
146*5c51f124SMoriah Waterland (void) snprintf(path, sizeof (path), "%s/respXXXXXX", tmpdir);
147*5c51f124SMoriah Waterland
148*5c51f124SMoriah Waterland resppath = mktemp(path);
149*5c51f124SMoriah Waterland if (resppath == NULL) {
150*5c51f124SMoriah Waterland progerr(ERR_TMPRESP);
151*5c51f124SMoriah Waterland return (99);
152*5c51f124SMoriah Waterland }
153*5c51f124SMoriah Waterland
154*5c51f124SMoriah Waterland /* Copy the contents of the user's response file to the working copy. */
155*5c51f124SMoriah Waterland
156*5c51f124SMoriah Waterland r = copyf(tpath, resppath, (time_t)0);
157*5c51f124SMoriah Waterland if (r != 0) {
158*5c51f124SMoriah Waterland progerr(ERR_NORESPCOPY, tpath, resppath);
159*5c51f124SMoriah Waterland return (99);
160*5c51f124SMoriah Waterland }
161*5c51f124SMoriah Waterland
162*5c51f124SMoriah Waterland /*
163*5c51f124SMoriah Waterland * Make it writable by the non-privileged installation user-id,
164*5c51f124SMoriah Waterland * but readable by the world.
165*5c51f124SMoriah Waterland */
166*5c51f124SMoriah Waterland
167*5c51f124SMoriah Waterland if (chmod(resppath, 0644) != 0) {
168*5c51f124SMoriah Waterland progerr(ERR_CHMOD, resppath);
169*5c51f124SMoriah Waterland return (99);
170*5c51f124SMoriah Waterland }
171*5c51f124SMoriah Waterland
172*5c51f124SMoriah Waterland respfile_ro = 0;
173*5c51f124SMoriah Waterland
174*5c51f124SMoriah Waterland return (0);
175*5c51f124SMoriah Waterland }
176*5c51f124SMoriah Waterland
177*5c51f124SMoriah Waterland /*
178*5c51f124SMoriah Waterland * This function establishes the response file passed on the command line if
179*5c51f124SMoriah Waterland * it's called with a valid string. If called with NULL, it checks to see if
180*5c51f124SMoriah Waterland * there's a response file already. If there isn't, it creates a temporary.
181*5c51f124SMoriah Waterland */
182*5c51f124SMoriah Waterland int
set_respfile(char * respfile,char * pkginst,int resp_stat)183*5c51f124SMoriah Waterland set_respfile(char *respfile, char *pkginst, int resp_stat)
184*5c51f124SMoriah Waterland {
185*5c51f124SMoriah Waterland if (respfile == NULL && !respfile_defined) {
186*5c51f124SMoriah Waterland /* A temporary response file needs to be constructed. */
187*5c51f124SMoriah Waterland (void) snprintf(path, sizeof (path), "%s/respXXXXXX", tmpdir);
188*5c51f124SMoriah Waterland resppath = mktemp(path);
189*5c51f124SMoriah Waterland if (resppath == NULL) {
190*5c51f124SMoriah Waterland progerr(ERR_TMPRESP);
191*5c51f124SMoriah Waterland return (99);
192*5c51f124SMoriah Waterland }
193*5c51f124SMoriah Waterland } else {
194*5c51f124SMoriah Waterland /* OK, we're being passed a response file or directory. */
195*5c51f124SMoriah Waterland if (isdir(respfile) == 0) {
196*5c51f124SMoriah Waterland (void) snprintf(path, sizeof (path),
197*5c51f124SMoriah Waterland "%s/%s", respfile, pkginst);
198*5c51f124SMoriah Waterland } else {
199*5c51f124SMoriah Waterland (void) strlcpy(path, respfile, sizeof (path));
200*5c51f124SMoriah Waterland }
201*5c51f124SMoriah Waterland
202*5c51f124SMoriah Waterland resppath = path;
203*5c51f124SMoriah Waterland respfile_ro = resp_stat;
204*5c51f124SMoriah Waterland }
205*5c51f124SMoriah Waterland
206*5c51f124SMoriah Waterland respfile_defined++;
207*5c51f124SMoriah Waterland
208*5c51f124SMoriah Waterland return (0);
209*5c51f124SMoriah Waterland }
210*5c51f124SMoriah Waterland
211*5c51f124SMoriah Waterland /* This exposes the working response file. */
212*5c51f124SMoriah Waterland char *
get_respfile(void)213*5c51f124SMoriah Waterland get_respfile(void)
214*5c51f124SMoriah Waterland {
215*5c51f124SMoriah Waterland return (resppath);
216*5c51f124SMoriah Waterland }
217*5c51f124SMoriah Waterland
218*5c51f124SMoriah Waterland /*
219*5c51f124SMoriah Waterland * Execute the request script if present assuming the response file
220*5c51f124SMoriah Waterland * isn't read only.
221*5c51f124SMoriah Waterland */
222*5c51f124SMoriah Waterland int
reqexec(int update,char * script,int non_abi_scripts,boolean_t enable_root_user)223*5c51f124SMoriah Waterland reqexec(int update, char *script, int non_abi_scripts,
224*5c51f124SMoriah Waterland boolean_t enable_root_user)
225*5c51f124SMoriah Waterland {
226*5c51f124SMoriah Waterland char *req_user;
227*5c51f124SMoriah Waterland
228*5c51f124SMoriah Waterland /*
229*5c51f124SMoriah Waterland * determine which alternative user to execute the request script as
230*5c51f124SMoriah Waterland * if the default user "install" is not defined.
231*5c51f124SMoriah Waterland */
232*5c51f124SMoriah Waterland
233*5c51f124SMoriah Waterland if (enable_root_user == B_TRUE) {
234*5c51f124SMoriah Waterland /* use the root user */
235*5c51f124SMoriah Waterland req_user = CHK_USER_ROOT;
236*5c51f124SMoriah Waterland } else if (non_abi_scripts != 0) {
237*5c51f124SMoriah Waterland /* non-compliant package user */
238*5c51f124SMoriah Waterland req_user = CHK_USER_NON;
239*5c51f124SMoriah Waterland } else {
240*5c51f124SMoriah Waterland /* standard non-privileged user */
241*5c51f124SMoriah Waterland req_user = CHK_USER_ALT;
242*5c51f124SMoriah Waterland }
243*5c51f124SMoriah Waterland
244*5c51f124SMoriah Waterland /*
245*5c51f124SMoriah Waterland * If we can't get to the the script or the response file, skip this.
246*5c51f124SMoriah Waterland */
247*5c51f124SMoriah Waterland if (access(script, F_OK) != 0 || respfile_ro)
248*5c51f124SMoriah Waterland return (0);
249*5c51f124SMoriah Waterland
250*5c51f124SMoriah Waterland /* No interact means no interact. */
251*5c51f124SMoriah Waterland if (echoGetFlag() == B_FALSE) {
252*5c51f124SMoriah Waterland ptext(stderr, ERR_INTR);
253*5c51f124SMoriah Waterland return (5);
254*5c51f124SMoriah Waterland }
255*5c51f124SMoriah Waterland
256*5c51f124SMoriah Waterland /* If there's no response file, create one. */
257*5c51f124SMoriah Waterland if (!respfile_defined)
258*5c51f124SMoriah Waterland if (set_respfile(NULL, NULL, 0))
259*5c51f124SMoriah Waterland return (99);
260*5c51f124SMoriah Waterland
261*5c51f124SMoriah Waterland /* Clear out the old response file (if there is one). */
262*5c51f124SMoriah Waterland if ((access(resppath, F_OK) == 0) && unlink(resppath)) {
263*5c51f124SMoriah Waterland progerr(ERR_RMRESP, resppath);
264*5c51f124SMoriah Waterland return (99);
265*5c51f124SMoriah Waterland }
266*5c51f124SMoriah Waterland
267*5c51f124SMoriah Waterland /*
268*5c51f124SMoriah Waterland * Create a zero length response file which is only writable
269*5c51f124SMoriah Waterland * by the non-privileged installation user-id, but is readable
270*5c51f124SMoriah Waterland * by the world
271*5c51f124SMoriah Waterland */
272*5c51f124SMoriah Waterland if ((fd = open(resppath, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644)) < 0) {
273*5c51f124SMoriah Waterland progerr(ERR_CRERESP, resppath);
274*5c51f124SMoriah Waterland return (99);
275*5c51f124SMoriah Waterland }
276*5c51f124SMoriah Waterland (void) close(fd);
277*5c51f124SMoriah Waterland
278*5c51f124SMoriah Waterland return (do_exec(update, script, resppath, REQ_STDIN, req_user));
279*5c51f124SMoriah Waterland }
280*5c51f124SMoriah Waterland
281*5c51f124SMoriah Waterland int
chkexec(int update,char * script)282*5c51f124SMoriah Waterland chkexec(int update, char *script)
283*5c51f124SMoriah Waterland {
284*5c51f124SMoriah Waterland /*
285*5c51f124SMoriah Waterland * If we're up against a read-only response file from the command
286*5c51f124SMoriah Waterland * line. Create a working copy.
287*5c51f124SMoriah Waterland */
288*5c51f124SMoriah Waterland if (respfile_ro) {
289*5c51f124SMoriah Waterland if (dup_respfile())
290*5c51f124SMoriah Waterland
291*5c51f124SMoriah Waterland return (99);
292*5c51f124SMoriah Waterland
293*5c51f124SMoriah Waterland /* Make sure we can get to it. */
294*5c51f124SMoriah Waterland if ((access(resppath, F_OK) != 0)) {
295*5c51f124SMoriah Waterland progerr(ERR_ACCRESP, resppath);
296*5c51f124SMoriah Waterland return (7);
297*5c51f124SMoriah Waterland }
298*5c51f124SMoriah Waterland }
299*5c51f124SMoriah Waterland
300*5c51f124SMoriah Waterland /* If there's no response file, create a fresh one. */
301*5c51f124SMoriah Waterland else if (!respfile_defined) {
302*5c51f124SMoriah Waterland if (set_respfile(NULL, NULL, 0))
303*5c51f124SMoriah Waterland return (99);
304*5c51f124SMoriah Waterland
305*5c51f124SMoriah Waterland /*
306*5c51f124SMoriah Waterland * create a zero length response file which is only writable
307*5c51f124SMoriah Waterland * by the non-priveledged installation user-id, but is readable
308*5c51f124SMoriah Waterland * by the world
309*5c51f124SMoriah Waterland */
310*5c51f124SMoriah Waterland fd = open(resppath, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644);
311*5c51f124SMoriah Waterland if (fd < 0) {
312*5c51f124SMoriah Waterland progerr(ERR_CRERESP, resppath);
313*5c51f124SMoriah Waterland return (99);
314*5c51f124SMoriah Waterland }
315*5c51f124SMoriah Waterland (void) close(fd);
316*5c51f124SMoriah Waterland }
317*5c51f124SMoriah Waterland
318*5c51f124SMoriah Waterland return (do_exec(update, script, resppath, CHK_STDIN, CHK_USER_ALT));
319*5c51f124SMoriah Waterland }
320*5c51f124SMoriah Waterland
321*5c51f124SMoriah Waterland static int
do_exec(int update,char * script,char * output,char * inport,char * alt_user)322*5c51f124SMoriah Waterland do_exec(int update, char *script, char *output, char *inport, char *alt_user)
323*5c51f124SMoriah Waterland {
324*5c51f124SMoriah Waterland char *gname;
325*5c51f124SMoriah Waterland char *tmp_script;
326*5c51f124SMoriah Waterland char *uname;
327*5c51f124SMoriah Waterland gid_t instgid;
328*5c51f124SMoriah Waterland int retcode = 0;
329*5c51f124SMoriah Waterland struct group *grp;
330*5c51f124SMoriah Waterland struct passwd *pwp;
331*5c51f124SMoriah Waterland uid_t instuid;
332*5c51f124SMoriah Waterland
333*5c51f124SMoriah Waterland /*
334*5c51f124SMoriah Waterland * Determine which user to run the request script as:
335*5c51f124SMoriah Waterland * - if CHK_USER is a valid user, run the script as CHK_USER
336*5c51f124SMoriah Waterland * - otherwise, if alt_user is a valid user, run the script
337*5c51f124SMoriah Waterland * -- as alt_user
338*5c51f124SMoriah Waterland * - otherwise, output an error message and return failure
339*5c51f124SMoriah Waterland */
340*5c51f124SMoriah Waterland
341*5c51f124SMoriah Waterland if ((pwp = getpwnam(CHK_USER)) != (struct passwd *)NULL) {
342*5c51f124SMoriah Waterland instuid = pwp->pw_uid;
343*5c51f124SMoriah Waterland uname = CHK_USER;
344*5c51f124SMoriah Waterland } else if ((pwp = getpwnam(alt_user)) != (struct passwd *)NULL) {
345*5c51f124SMoriah Waterland instuid = pwp->pw_uid;
346*5c51f124SMoriah Waterland uname = alt_user;
347*5c51f124SMoriah Waterland } else {
348*5c51f124SMoriah Waterland ptext(stderr, ERR_BADUSER, CHK_USER, CHK_USER_ALT);
349*5c51f124SMoriah Waterland return (1);
350*5c51f124SMoriah Waterland }
351*5c51f124SMoriah Waterland
352*5c51f124SMoriah Waterland /*
353*5c51f124SMoriah Waterland * Determine which group to run the request script as:
354*5c51f124SMoriah Waterland * - If CHK_GRP is a valid group, run the script as CHK_GRP
355*5c51f124SMoriah Waterland * - otherwise, assume group "1" user "other"
356*5c51f124SMoriah Waterland */
357*5c51f124SMoriah Waterland
358*5c51f124SMoriah Waterland if ((grp = getgrnam(CHK_GRP)) != (struct group *)NULL) {
359*5c51f124SMoriah Waterland instgid = grp->gr_gid;
360*5c51f124SMoriah Waterland gname = CHK_GRP;
361*5c51f124SMoriah Waterland } else {
362*5c51f124SMoriah Waterland instgid = (gid_t)1; /* "other" group id */
363*5c51f124SMoriah Waterland gname = "other"; /* "other" group name */
364*5c51f124SMoriah Waterland }
365*5c51f124SMoriah Waterland
366*5c51f124SMoriah Waterland echoDebug(DBG_DO_EXEC_REQUEST_USER, script, output, uname, instuid,
367*5c51f124SMoriah Waterland gname, instgid);
368*5c51f124SMoriah Waterland
369*5c51f124SMoriah Waterland (void) chown(output, instuid, instgid);
370*5c51f124SMoriah Waterland
371*5c51f124SMoriah Waterland /*
372*5c51f124SMoriah Waterland * Copy the checkinstall script to tmpdir in case parent directories
373*5c51f124SMoriah Waterland * are restrictive, i.e. 700. Only do this for non updates, i.e.
374*5c51f124SMoriah Waterland * package installs and not patch package installs.
375*5c51f124SMoriah Waterland */
376*5c51f124SMoriah Waterland if (update) {
377*5c51f124SMoriah Waterland tmp_script = strdup(script);
378*5c51f124SMoriah Waterland } else if ((tmp_script = dup_chkinstall(script)) == NULL) {
379*5c51f124SMoriah Waterland /* Use the original checkinstall script */
380*5c51f124SMoriah Waterland tmp_script = strdup(script);
381*5c51f124SMoriah Waterland }
382*5c51f124SMoriah Waterland
383*5c51f124SMoriah Waterland if (pkgverbose)
384*5c51f124SMoriah Waterland retcode = pkgexecl(inport, CHK_STDOUT, uname, CHK_GRP, SHELL,
385*5c51f124SMoriah Waterland "-x", tmp_script, output, NULL);
386*5c51f124SMoriah Waterland else
387*5c51f124SMoriah Waterland retcode = pkgexecl(inport, CHK_STDOUT, uname, CHK_GRP, SHELL,
388*5c51f124SMoriah Waterland tmp_script, output, NULL);
389*5c51f124SMoriah Waterland
390*5c51f124SMoriah Waterland free(tmp_script);
391*5c51f124SMoriah Waterland return (retcode);
392*5c51f124SMoriah Waterland }
393