1*9781SMoriah.Waterland@Sun.COM /*
2*9781SMoriah.Waterland@Sun.COM * CDDL HEADER START
3*9781SMoriah.Waterland@Sun.COM *
4*9781SMoriah.Waterland@Sun.COM * The contents of this file are subject to the terms of the
5*9781SMoriah.Waterland@Sun.COM * Common Development and Distribution License (the "License").
6*9781SMoriah.Waterland@Sun.COM * You may not use this file except in compliance with the License.
7*9781SMoriah.Waterland@Sun.COM *
8*9781SMoriah.Waterland@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9781SMoriah.Waterland@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*9781SMoriah.Waterland@Sun.COM * See the License for the specific language governing permissions
11*9781SMoriah.Waterland@Sun.COM * and limitations under the License.
12*9781SMoriah.Waterland@Sun.COM *
13*9781SMoriah.Waterland@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*9781SMoriah.Waterland@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9781SMoriah.Waterland@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*9781SMoriah.Waterland@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*9781SMoriah.Waterland@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*9781SMoriah.Waterland@Sun.COM *
19*9781SMoriah.Waterland@Sun.COM * CDDL HEADER END
20*9781SMoriah.Waterland@Sun.COM */
21*9781SMoriah.Waterland@Sun.COM
22*9781SMoriah.Waterland@Sun.COM /*
23*9781SMoriah.Waterland@Sun.COM * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*9781SMoriah.Waterland@Sun.COM * Use is subject to license terms.
25*9781SMoriah.Waterland@Sun.COM */
26*9781SMoriah.Waterland@Sun.COM
27*9781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28*9781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
29*9781SMoriah.Waterland@Sun.COM
30*9781SMoriah.Waterland@Sun.COM
31*9781SMoriah.Waterland@Sun.COM /*
32*9781SMoriah.Waterland@Sun.COM * System includes
33*9781SMoriah.Waterland@Sun.COM */
34*9781SMoriah.Waterland@Sun.COM
35*9781SMoriah.Waterland@Sun.COM #include <stdio.h>
36*9781SMoriah.Waterland@Sun.COM #include <string.h>
37*9781SMoriah.Waterland@Sun.COM #include <stdlib.h>
38*9781SMoriah.Waterland@Sun.COM #include <unistd.h>
39*9781SMoriah.Waterland@Sun.COM #include <utime.h>
40*9781SMoriah.Waterland@Sun.COM #include <locale.h>
41*9781SMoriah.Waterland@Sun.COM #include <libintl.h>
42*9781SMoriah.Waterland@Sun.COM #include <pkglocs.h>
43*9781SMoriah.Waterland@Sun.COM #include <errno.h>
44*9781SMoriah.Waterland@Sun.COM #include <fcntl.h>
45*9781SMoriah.Waterland@Sun.COM #include <sys/types.h>
46*9781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
47*9781SMoriah.Waterland@Sun.COM
48*9781SMoriah.Waterland@Sun.COM /*
49*9781SMoriah.Waterland@Sun.COM * consolidation pkg command library includes
50*9781SMoriah.Waterland@Sun.COM */
51*9781SMoriah.Waterland@Sun.COM
52*9781SMoriah.Waterland@Sun.COM #include <pkglib.h>
53*9781SMoriah.Waterland@Sun.COM
54*9781SMoriah.Waterland@Sun.COM /*
55*9781SMoriah.Waterland@Sun.COM * local pkg command library includes
56*9781SMoriah.Waterland@Sun.COM */
57*9781SMoriah.Waterland@Sun.COM
58*9781SMoriah.Waterland@Sun.COM #include "libadm.h"
59*9781SMoriah.Waterland@Sun.COM #include "libinst.h"
60*9781SMoriah.Waterland@Sun.COM #include "install.h"
61*9781SMoriah.Waterland@Sun.COM #include "messages.h"
62*9781SMoriah.Waterland@Sun.COM #include "pkginstall.h"
63*9781SMoriah.Waterland@Sun.COM
64*9781SMoriah.Waterland@Sun.COM /*
65*9781SMoriah.Waterland@Sun.COM * forward declarations
66*9781SMoriah.Waterland@Sun.COM */
67*9781SMoriah.Waterland@Sun.COM
68*9781SMoriah.Waterland@Sun.COM static int write_file(char **r_linknam, int a_ctrl, mode_t a_mode,
69*9781SMoriah.Waterland@Sun.COM char *a_file);
70*9781SMoriah.Waterland@Sun.COM static int create_path(int a_ctrl, char *a_file);
71*9781SMoriah.Waterland@Sun.COM
72*9781SMoriah.Waterland@Sun.COM /*
73*9781SMoriah.Waterland@Sun.COM * Name: cppath
74*9781SMoriah.Waterland@Sun.COM * Description: copy a path object (install new file on system)
75*9781SMoriah.Waterland@Sun.COM * Arguments:
76*9781SMoriah.Waterland@Sun.COM * - a_cntrl - determine how the destination file mode is set:
77*9781SMoriah.Waterland@Sun.COM * |= MODE_0666 - force mode to 0666
78*9781SMoriah.Waterland@Sun.COM * |= MODE_SET - mode is a_mode (no mask SET?ID bits)
79*9781SMoriah.Waterland@Sun.COM * |= MODE_SRC - mode from source file (mask SET?ID bits)
80*9781SMoriah.Waterland@Sun.COM * |= DIR_DISPLAY - display "%s <implied directory>" if directory created
81*9781SMoriah.Waterland@Sun.COM * - a_srcPath - path to source to copy
82*9781SMoriah.Waterland@Sun.COM * - a_dstPath - path to copy source to
83*9781SMoriah.Waterland@Sun.COM * - a_mode - mode to set a_dstpath to (mode controlled by a_ctrl)
84*9781SMoriah.Waterland@Sun.COM * Returns: int
85*9781SMoriah.Waterland@Sun.COM * == 0 - success
86*9781SMoriah.Waterland@Sun.COM * != 0 - failure
87*9781SMoriah.Waterland@Sun.COM */
88*9781SMoriah.Waterland@Sun.COM
89*9781SMoriah.Waterland@Sun.COM int
cppath(int a_ctrl,char * a_srcPath,char * a_dstPath,mode_t a_mode)90*9781SMoriah.Waterland@Sun.COM cppath(int a_ctrl, char *a_srcPath, char *a_dstPath, mode_t a_mode)
91*9781SMoriah.Waterland@Sun.COM {
92*9781SMoriah.Waterland@Sun.COM char *linknam = (char *)NULL;
93*9781SMoriah.Waterland@Sun.COM int dstFd;
94*9781SMoriah.Waterland@Sun.COM int len;
95*9781SMoriah.Waterland@Sun.COM int srcFd;
96*9781SMoriah.Waterland@Sun.COM long status;
97*9781SMoriah.Waterland@Sun.COM struct stat srcStatbuf;
98*9781SMoriah.Waterland@Sun.COM struct utimbuf times;
99*9781SMoriah.Waterland@Sun.COM
100*9781SMoriah.Waterland@Sun.COM /* entry debugging info */
101*9781SMoriah.Waterland@Sun.COM
102*9781SMoriah.Waterland@Sun.COM echoDebug(DBG_CPPATH_ENTRY, a_ctrl, a_mode, a_srcPath, a_dstPath);
103*9781SMoriah.Waterland@Sun.COM
104*9781SMoriah.Waterland@Sun.COM /* open source file for reading */
105*9781SMoriah.Waterland@Sun.COM
106*9781SMoriah.Waterland@Sun.COM srcFd = open(a_srcPath, O_RDONLY);
107*9781SMoriah.Waterland@Sun.COM if (srcFd < 0) {
108*9781SMoriah.Waterland@Sun.COM progerr(ERR_OPEN_READ, a_srcPath,
109*9781SMoriah.Waterland@Sun.COM errno, strerror(errno));
110*9781SMoriah.Waterland@Sun.COM return (1);
111*9781SMoriah.Waterland@Sun.COM }
112*9781SMoriah.Waterland@Sun.COM
113*9781SMoriah.Waterland@Sun.COM /* obtain file status of source file */
114*9781SMoriah.Waterland@Sun.COM
115*9781SMoriah.Waterland@Sun.COM if (fstat(srcFd, &srcStatbuf) != 0) {
116*9781SMoriah.Waterland@Sun.COM progerr(ERR_FSTAT, srcFd, a_srcPath, errno, strerror(errno));
117*9781SMoriah.Waterland@Sun.COM (void) close(srcFd);
118*9781SMoriah.Waterland@Sun.COM return (1);
119*9781SMoriah.Waterland@Sun.COM }
120*9781SMoriah.Waterland@Sun.COM
121*9781SMoriah.Waterland@Sun.COM /*
122*9781SMoriah.Waterland@Sun.COM * Determine the permissions mode for the destination:
123*9781SMoriah.Waterland@Sun.COM * - if MODE_SET is specified:
124*9781SMoriah.Waterland@Sun.COM * --> use a_mode (do not mask off any portion)
125*9781SMoriah.Waterland@Sun.COM * --> If a_mode is unknown (? in the pkgmap), then the file gets
126*9781SMoriah.Waterland@Sun.COM * --> installed with the default 0644 mode
127*9781SMoriah.Waterland@Sun.COM * - if MODE_SRC is specified:
128*9781SMoriah.Waterland@Sun.COM * --> use the mode of the source (srcStatbuf.st_mode) but mask off all
129*9781SMoriah.Waterland@Sun.COM * --> non-access mode bits (remove SET?UID bits)
130*9781SMoriah.Waterland@Sun.COM * - otherwise:
131*9781SMoriah.Waterland@Sun.COM * --> use 0666
132*9781SMoriah.Waterland@Sun.COM */
133*9781SMoriah.Waterland@Sun.COM
134*9781SMoriah.Waterland@Sun.COM if (a_ctrl & MODE_SET) {
135*9781SMoriah.Waterland@Sun.COM mode_t usemode;
136*9781SMoriah.Waterland@Sun.COM
137*9781SMoriah.Waterland@Sun.COM usemode = (a_mode ^ BADMODE) ? a_mode : 0644;
138*9781SMoriah.Waterland@Sun.COM if (a_mode != usemode && usemode == 0644) {
139*9781SMoriah.Waterland@Sun.COM logerr(WRN_DEF_MODE, a_dstPath);
140*9781SMoriah.Waterland@Sun.COM a_mode = usemode;
141*9781SMoriah.Waterland@Sun.COM }
142*9781SMoriah.Waterland@Sun.COM } else if (a_ctrl & MODE_SRC) {
143*9781SMoriah.Waterland@Sun.COM a_mode = (srcStatbuf.st_mode & S_IAMB);
144*9781SMoriah.Waterland@Sun.COM } else {
145*9781SMoriah.Waterland@Sun.COM a_mode = 0666;
146*9781SMoriah.Waterland@Sun.COM }
147*9781SMoriah.Waterland@Sun.COM
148*9781SMoriah.Waterland@Sun.COM /*
149*9781SMoriah.Waterland@Sun.COM * Get fd of newly created destination file or, if this
150*9781SMoriah.Waterland@Sun.COM * is an overwrite, a temporary file (linknam).
151*9781SMoriah.Waterland@Sun.COM */
152*9781SMoriah.Waterland@Sun.COM
153*9781SMoriah.Waterland@Sun.COM dstFd = write_file(&linknam, a_ctrl, a_mode, a_dstPath);
154*9781SMoriah.Waterland@Sun.COM if (dstFd < 0) {
155*9781SMoriah.Waterland@Sun.COM (void) close(srcFd);
156*9781SMoriah.Waterland@Sun.COM return (1);
157*9781SMoriah.Waterland@Sun.COM }
158*9781SMoriah.Waterland@Sun.COM
159*9781SMoriah.Waterland@Sun.COM /*
160*9781SMoriah.Waterland@Sun.COM * source and target files are open: copy data
161*9781SMoriah.Waterland@Sun.COM */
162*9781SMoriah.Waterland@Sun.COM
163*9781SMoriah.Waterland@Sun.COM status = copyFile(srcFd, dstFd, a_srcPath, a_dstPath, &srcStatbuf, 0);
164*9781SMoriah.Waterland@Sun.COM
165*9781SMoriah.Waterland@Sun.COM (void) close(srcFd);
166*9781SMoriah.Waterland@Sun.COM (void) close(dstFd);
167*9781SMoriah.Waterland@Sun.COM
168*9781SMoriah.Waterland@Sun.COM if (status != 0) {
169*9781SMoriah.Waterland@Sun.COM progerr(ERR_INPUT, a_srcPath, errno, strerror(errno));
170*9781SMoriah.Waterland@Sun.COM if (linknam) {
171*9781SMoriah.Waterland@Sun.COM (void) remove(linknam);
172*9781SMoriah.Waterland@Sun.COM }
173*9781SMoriah.Waterland@Sun.COM return (1);
174*9781SMoriah.Waterland@Sun.COM }
175*9781SMoriah.Waterland@Sun.COM
176*9781SMoriah.Waterland@Sun.COM /*
177*9781SMoriah.Waterland@Sun.COM * If this is an overwrite, rename temp over original
178*9781SMoriah.Waterland@Sun.COM */
179*9781SMoriah.Waterland@Sun.COM
180*9781SMoriah.Waterland@Sun.COM if ((linknam != (char *)NULL) && (rename(linknam, a_dstPath) != 0)) {
181*9781SMoriah.Waterland@Sun.COM FILE *logfp = (FILE *)NULL;
182*9781SMoriah.Waterland@Sun.COM char busylog[PATH_MAX];
183*9781SMoriah.Waterland@Sun.COM
184*9781SMoriah.Waterland@Sun.COM /* output log message if busy else program error */
185*9781SMoriah.Waterland@Sun.COM
186*9781SMoriah.Waterland@Sun.COM if (errno == ETXTBSY) {
187*9781SMoriah.Waterland@Sun.COM logerr(MSG_PROCMV, linknam);
188*9781SMoriah.Waterland@Sun.COM } else {
189*9781SMoriah.Waterland@Sun.COM progerr(ERR_OUTPUT_WRITING, a_dstPath, errno,
190*9781SMoriah.Waterland@Sun.COM strerror(errno));
191*9781SMoriah.Waterland@Sun.COM }
192*9781SMoriah.Waterland@Sun.COM
193*9781SMoriah.Waterland@Sun.COM (void) remove(linknam);
194*9781SMoriah.Waterland@Sun.COM
195*9781SMoriah.Waterland@Sun.COM /* open the log file and append log entry */
196*9781SMoriah.Waterland@Sun.COM
197*9781SMoriah.Waterland@Sun.COM len = snprintf(busylog, sizeof (busylog),
198*9781SMoriah.Waterland@Sun.COM "%s/textbusy", get_PKGADM());
199*9781SMoriah.Waterland@Sun.COM if (len > sizeof (busylog)) {
200*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, get_PKGADM(),
201*9781SMoriah.Waterland@Sun.COM "textbusy");
202*9781SMoriah.Waterland@Sun.COM } else {
203*9781SMoriah.Waterland@Sun.COM logfp = fopen(busylog, "a");
204*9781SMoriah.Waterland@Sun.COM if (logfp == NULL) {
205*9781SMoriah.Waterland@Sun.COM progerr(ERR_LOG, busylog, errno,
206*9781SMoriah.Waterland@Sun.COM strerror(errno));
207*9781SMoriah.Waterland@Sun.COM } else {
208*9781SMoriah.Waterland@Sun.COM (void) fprintf(logfp, "%s\n", linknam);
209*9781SMoriah.Waterland@Sun.COM (void) fclose(logfp);
210*9781SMoriah.Waterland@Sun.COM }
211*9781SMoriah.Waterland@Sun.COM }
212*9781SMoriah.Waterland@Sun.COM }
213*9781SMoriah.Waterland@Sun.COM
214*9781SMoriah.Waterland@Sun.COM /* set access/modification times for target */
215*9781SMoriah.Waterland@Sun.COM
216*9781SMoriah.Waterland@Sun.COM times.actime = srcStatbuf.st_atime;
217*9781SMoriah.Waterland@Sun.COM times.modtime = srcStatbuf.st_mtime;
218*9781SMoriah.Waterland@Sun.COM
219*9781SMoriah.Waterland@Sun.COM if (utime(a_dstPath, ×) != 0) {
220*9781SMoriah.Waterland@Sun.COM progerr(ERR_MODTIM, a_dstPath, errno, strerror(errno));
221*9781SMoriah.Waterland@Sun.COM return (1);
222*9781SMoriah.Waterland@Sun.COM }
223*9781SMoriah.Waterland@Sun.COM
224*9781SMoriah.Waterland@Sun.COM /* success! */
225*9781SMoriah.Waterland@Sun.COM
226*9781SMoriah.Waterland@Sun.COM return (0);
227*9781SMoriah.Waterland@Sun.COM }
228*9781SMoriah.Waterland@Sun.COM
229*9781SMoriah.Waterland@Sun.COM /*
230*9781SMoriah.Waterland@Sun.COM * This function creates all of the directory components of the specified path.
231*9781SMoriah.Waterland@Sun.COM */
232*9781SMoriah.Waterland@Sun.COM static int
create_path(int a_ctrl,char * a_file)233*9781SMoriah.Waterland@Sun.COM create_path(int a_ctrl, char *a_file)
234*9781SMoriah.Waterland@Sun.COM {
235*9781SMoriah.Waterland@Sun.COM char *pt;
236*9781SMoriah.Waterland@Sun.COM int found = 0;
237*9781SMoriah.Waterland@Sun.COM
238*9781SMoriah.Waterland@Sun.COM for (pt = a_file; *pt; pt++) {
239*9781SMoriah.Waterland@Sun.COM /* continue if not at path separator or at start of path */
240*9781SMoriah.Waterland@Sun.COM
241*9781SMoriah.Waterland@Sun.COM if ((*pt != '/') || (pt == a_file)) {
242*9781SMoriah.Waterland@Sun.COM continue;
243*9781SMoriah.Waterland@Sun.COM }
244*9781SMoriah.Waterland@Sun.COM
245*9781SMoriah.Waterland@Sun.COM /* at '/' - terminate path at current entry */
246*9781SMoriah.Waterland@Sun.COM
247*9781SMoriah.Waterland@Sun.COM *pt = '\0';
248*9781SMoriah.Waterland@Sun.COM
249*9781SMoriah.Waterland@Sun.COM /* continue if path element exists */
250*9781SMoriah.Waterland@Sun.COM
251*9781SMoriah.Waterland@Sun.COM if (access(a_file, F_OK) == 0) {
252*9781SMoriah.Waterland@Sun.COM *pt = '/';
253*9781SMoriah.Waterland@Sun.COM continue;
254*9781SMoriah.Waterland@Sun.COM }
255*9781SMoriah.Waterland@Sun.COM
256*9781SMoriah.Waterland@Sun.COM /* create directory in path */
257*9781SMoriah.Waterland@Sun.COM
258*9781SMoriah.Waterland@Sun.COM if (mkdir(a_file, 0755)) {
259*9781SMoriah.Waterland@Sun.COM progerr(ERR_MAKE_DIR, a_file, errno, strerror(errno));
260*9781SMoriah.Waterland@Sun.COM *pt = '/';
261*9781SMoriah.Waterland@Sun.COM return (1);
262*9781SMoriah.Waterland@Sun.COM }
263*9781SMoriah.Waterland@Sun.COM
264*9781SMoriah.Waterland@Sun.COM /* display 'implied directory created' message */
265*9781SMoriah.Waterland@Sun.COM
266*9781SMoriah.Waterland@Sun.COM if (a_ctrl & DIR_DISPLAY) {
267*9781SMoriah.Waterland@Sun.COM echo(MSG_IMPDIR, a_file);
268*9781SMoriah.Waterland@Sun.COM }
269*9781SMoriah.Waterland@Sun.COM
270*9781SMoriah.Waterland@Sun.COM found++;
271*9781SMoriah.Waterland@Sun.COM
272*9781SMoriah.Waterland@Sun.COM *pt = '/';
273*9781SMoriah.Waterland@Sun.COM }
274*9781SMoriah.Waterland@Sun.COM
275*9781SMoriah.Waterland@Sun.COM return (!found);
276*9781SMoriah.Waterland@Sun.COM }
277*9781SMoriah.Waterland@Sun.COM
278*9781SMoriah.Waterland@Sun.COM /*
279*9781SMoriah.Waterland@Sun.COM * Name: write_file
280*9781SMoriah.Waterland@Sun.COM * Description: creates a new destination file if the file does not already
281*9781SMoriah.Waterland@Sun.COM * exist; otherwise, creates a temporary file and places a
282*9781SMoriah.Waterland@Sun.COM * pointer to the temporary file name in 'r_linknam'.
283*9781SMoriah.Waterland@Sun.COM * Arguments: r_linknam - pointer to (char*) where name of temporary file
284*9781SMoriah.Waterland@Sun.COM * created is returned
285*9781SMoriah.Waterland@Sun.COM * a_ctrl - determine if the destination file name is displayed:
286*9781SMoriah.Waterland@Sun.COM * |= DIR_DISPLAY - display "%s <implied directory>"
287*9781SMoriah.Waterland@Sun.COM * if directory created
288*9781SMoriah.Waterland@Sun.COM * a_mode - permissions mode to set a_file to
289*9781SMoriah.Waterland@Sun.COM * a_file - name of destination file to open
290*9781SMoriah.Waterland@Sun.COM * Returns: int
291*9781SMoriah.Waterland@Sun.COM * success - file descriptor of the file it opened.
292*9781SMoriah.Waterland@Sun.COM * failure - returns -1
293*9781SMoriah.Waterland@Sun.COM */
294*9781SMoriah.Waterland@Sun.COM
295*9781SMoriah.Waterland@Sun.COM static int
write_file(char ** r_linknam,int a_ctrl,mode_t a_mode,char * a_file)296*9781SMoriah.Waterland@Sun.COM write_file(char **r_linknam, int a_ctrl, mode_t a_mode, char *a_file)
297*9781SMoriah.Waterland@Sun.COM {
298*9781SMoriah.Waterland@Sun.COM int len;
299*9781SMoriah.Waterland@Sun.COM int fd = -1;
300*9781SMoriah.Waterland@Sun.COM static char loc_link[PATH_MAX];
301*9781SMoriah.Waterland@Sun.COM
302*9781SMoriah.Waterland@Sun.COM /* entry debugging */
303*9781SMoriah.Waterland@Sun.COM
304*9781SMoriah.Waterland@Sun.COM echoDebug(DBG_WRITEFILE_ENTRY, a_ctrl, a_mode, a_file);
305*9781SMoriah.Waterland@Sun.COM
306*9781SMoriah.Waterland@Sun.COM /* reset pointer to returned 'temporary file name' */
307*9781SMoriah.Waterland@Sun.COM
308*9781SMoriah.Waterland@Sun.COM *r_linknam = (char *)NULL;
309*9781SMoriah.Waterland@Sun.COM
310*9781SMoriah.Waterland@Sun.COM /*
311*9781SMoriah.Waterland@Sun.COM * If we are overwriting an existing file, arrange to replace
312*9781SMoriah.Waterland@Sun.COM * it transparently.
313*9781SMoriah.Waterland@Sun.COM */
314*9781SMoriah.Waterland@Sun.COM
315*9781SMoriah.Waterland@Sun.COM if (access(a_file, F_OK) == 0) {
316*9781SMoriah.Waterland@Sun.COM /*
317*9781SMoriah.Waterland@Sun.COM * link the file to be copied to a temporary name in case
318*9781SMoriah.Waterland@Sun.COM * it is executing or it is being written/used (e.g., a shell
319*9781SMoriah.Waterland@Sun.COM * script currently being executed
320*9781SMoriah.Waterland@Sun.COM */
321*9781SMoriah.Waterland@Sun.COM
322*9781SMoriah.Waterland@Sun.COM if (!RELATIVE(a_file)) {
323*9781SMoriah.Waterland@Sun.COM len = snprintf(loc_link, sizeof (loc_link),
324*9781SMoriah.Waterland@Sun.COM "%sXXXXXX", a_file);
325*9781SMoriah.Waterland@Sun.COM if (len > sizeof (loc_link)) {
326*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, a_file, "XXXXXX");
327*9781SMoriah.Waterland@Sun.COM }
328*9781SMoriah.Waterland@Sun.COM } else {
329*9781SMoriah.Waterland@Sun.COM logerr(WRN_RELATIVE, a_file);
330*9781SMoriah.Waterland@Sun.COM len = snprintf(loc_link, sizeof (loc_link),
331*9781SMoriah.Waterland@Sun.COM "./%sXXXXXX", a_file);
332*9781SMoriah.Waterland@Sun.COM if (len > sizeof (loc_link)) {
333*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_3, "./", a_file,
334*9781SMoriah.Waterland@Sun.COM "XXXXXX");
335*9781SMoriah.Waterland@Sun.COM }
336*9781SMoriah.Waterland@Sun.COM }
337*9781SMoriah.Waterland@Sun.COM
338*9781SMoriah.Waterland@Sun.COM /* create and open temporary file */
339*9781SMoriah.Waterland@Sun.COM
340*9781SMoriah.Waterland@Sun.COM fd = mkstemp(loc_link);
341*9781SMoriah.Waterland@Sun.COM if (fd == -1) {
342*9781SMoriah.Waterland@Sun.COM progerr(ERR_MKTEMP, loc_link, errno, strerror(errno));
343*9781SMoriah.Waterland@Sun.COM return (-1);
344*9781SMoriah.Waterland@Sun.COM }
345*9781SMoriah.Waterland@Sun.COM
346*9781SMoriah.Waterland@Sun.COM /* remember name of temporary file */
347*9781SMoriah.Waterland@Sun.COM
348*9781SMoriah.Waterland@Sun.COM *r_linknam = loc_link;
349*9781SMoriah.Waterland@Sun.COM
350*9781SMoriah.Waterland@Sun.COM /* make sure temporary file has correct mode */
351*9781SMoriah.Waterland@Sun.COM
352*9781SMoriah.Waterland@Sun.COM if (fchmod(fd, a_mode) < 0) {
353*9781SMoriah.Waterland@Sun.COM progerr(ERR_FCHMOD, loc_link, a_mode, errno,
354*9781SMoriah.Waterland@Sun.COM strerror(errno));
355*9781SMoriah.Waterland@Sun.COM }
356*9781SMoriah.Waterland@Sun.COM
357*9781SMoriah.Waterland@Sun.COM return (fd);
358*9781SMoriah.Waterland@Sun.COM }
359*9781SMoriah.Waterland@Sun.COM
360*9781SMoriah.Waterland@Sun.COM /*
361*9781SMoriah.Waterland@Sun.COM * We are not overwriting an existing file, create a new one directly.
362*9781SMoriah.Waterland@Sun.COM */
363*9781SMoriah.Waterland@Sun.COM
364*9781SMoriah.Waterland@Sun.COM fd = open(a_file, O_WRONLY | O_CREAT | O_TRUNC, a_mode);
365*9781SMoriah.Waterland@Sun.COM if (fd == -1) {
366*9781SMoriah.Waterland@Sun.COM if (create_path(a_ctrl, a_file) == 0) {
367*9781SMoriah.Waterland@Sun.COM fd = open(a_file, O_WRONLY | O_CREAT | O_TRUNC, a_mode);
368*9781SMoriah.Waterland@Sun.COM }
369*9781SMoriah.Waterland@Sun.COM }
370*9781SMoriah.Waterland@Sun.COM
371*9781SMoriah.Waterland@Sun.COM if (fd == -1) {
372*9781SMoriah.Waterland@Sun.COM progerr(ERR_OPEN_WRITE, a_file, errno, strerror(errno));
373*9781SMoriah.Waterland@Sun.COM }
374*9781SMoriah.Waterland@Sun.COM
375*9781SMoriah.Waterland@Sun.COM return (fd);
376*9781SMoriah.Waterland@Sun.COM }
377