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 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 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 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