# # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # Copyright 2015, Richard Lowe. # Copyright 2019 RackTop Systems. LIBRARY = libvroot.a VERS = .1 OBJECTS = access.o \ args.o \ chdir.o \ chmod.o \ chown.o \ chroot.o \ creat.o \ execve.o \ lock.o \ lstat.o \ mkdir.o \ mount.o \ open.o \ readlink.o \ report.o \ rmdir.o \ stat.o \ truncate.o \ unlink.o \ utimes.o \ vroot.o \ setenv.o include $(SRC)/lib/Makefile.lib include ../../Makefile.com POFILE = libvroot.po POFILES = $(OBJECTS:%.o=%.po) LIBS = $(LIBRARY) SRCDIR = ../ MAPFILES= CPPFLAGS += -D_FILE_OFFSET_BITS=64 CCERRWARN += -Wno-unused-variable CCERRWARN += -Wno-parentheses all: $(LIBS) install: all $(POFILE): $(POFILES) $(CAT) $(POFILES) > $@ _msg: $(MSGDOMAIN) $(POFILE) $(RM) $(MSGDOMAIN)/$(POFILE) $(CP) $(POFILE) $(MSGDOMAIN) include $(SRC)/lib/Makefile.targ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include static int access_thunk(char *path) { vroot_result= access(path, vroot_args.access.mode); return((vroot_result == 0) || (errno != ENOENT)); } int access_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot) { vroot_args.access.mode= mode; translate_with_thunk(path, access_thunk, vroot_path, vroot_vroot, rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include union Args vroot_args; int vroot_result; /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include static int chdir_thunk(char *path) { vroot_result= chdir(path); return(vroot_result == 0); } int chdir_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot) { translate_with_thunk(path, chdir_thunk, vroot_path, vroot_vroot, rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include extern int chmod(const char *path, mode_t mode); #include #include static int chmod_thunk(char *path) { vroot_result= chmod(path, vroot_args.chmod.mode); return(vroot_result == 0); } int chmod_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot) { vroot_args.chmod.mode= mode; translate_with_thunk(path, chmod_thunk, vroot_path, vroot_vroot, rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include extern int chown(const char *path, uid_t owner, gid_t group); #include #include static int chown_thunk(char *path) { vroot_result= chown(path, vroot_args.chown.user, vroot_args.chown.group); return(vroot_result == 0); } int chown_vroot(char *path, int user, int group, pathpt vroot_path, pathpt vroot_vroot) { vroot_args.chown.user= user; vroot_args.chown.group= group; translate_with_thunk(path, chown_thunk, vroot_path, vroot_vroot, rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include extern int chroot(const char *path); #include #include static int chroot_thunk(char *path) { vroot_result= chroot(path); return(vroot_result == 0); } int chroot_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot) { translate_with_thunk(path, chroot_thunk, vroot_path, vroot_vroot, rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include extern int creat(const char *path, mode_t mode); #include #include static int creat_thunk(char *path) { vroot_result= creat(path, vroot_args.creat.mode); return(vroot_result >= 0); } int creat_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot) { vroot_args.creat.mode= mode; translate_with_thunk(path, creat_thunk, vroot_path, vroot_vroot, rw_write); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include extern int execve (const char *path, char *const argv[], char *const envp[]); #include #include static int execve_thunk(char *path) { execve(path, vroot_args.execve.argv, vroot_args.execve.environ); switch (errno) { case ETXTBSY: case ENOEXEC: return 1; default: return 0; } } int execve_vroot(char *path, char **argv, char **environ, pathpt vroot_path, pathpt vroot_vroot) { vroot_args.execve.argv= argv; vroot_args.execve.environ= environ; translate_with_thunk(path, execve_thunk, vroot_path, vroot_vroot, rw_read); return(-1); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include #include #include #include #include #include /* errno */ #include static void file_lock_error(char *msg, char *file, const char *str, char *arg1, char * arg2); #define BLOCK_INTERUPTS sigfillset(&newset) ; \ sigprocmask(SIG_SETMASK, &newset, &oldset) #define UNBLOCK_INTERUPTS \ sigprocmask(SIG_SETMASK, &oldset, &newset) /* * This code stolen from the NSE library and changed to not depend * upon any NSE routines or header files. * * Simple file locking. * Create a symlink to a file. The "test and set" will be * atomic as creating the symlink provides both functions. * * The timeout value specifies how long to wait for stale locks * to disappear. If the lock is more than 'timeout' seconds old * then it is ok to blow it away. This part has a small window * of vunerability as the operations of testing the time, * removing the lock and creating a new one are not atomic. * It would be possible for two processes to both decide to blow * away the lock and then have process A remove the lock and establish * its own, and then then have process B remove the lock which accidentily * removes A's lock rather than the stale one. * * A further complication is with the NFS. If the file in question is * being served by an NFS server, then its time is set by that server. * We can not use the time on the client machine to check for a stale * lock. Therefore, a temp file on the server is created to get * the servers current time. * * Returns an error message. NULL return means the lock was obtained. * * 12/6/91 Added the parameter "file_locked". Before this parameter * was added, the calling procedure would have to wait for file_lock() * to return before it sets the flag. If the user interrupted "make" * between the time the lock was acquired and the time file_lock() * returns, make wouldn't know that the file has been locked, and therefore * it wouldn' remove the lock. Setting the flag right after locking the file * makes this window much smaller. */ int file_lock(char *name, char *lockname, int *file_locked, int timeout) { int counter = 0; static char msg[MAXPATHLEN+1]; int printed_warning = 0; int r; struct stat statb; sigset_t newset; sigset_t oldset; *file_locked = 0; if (timeout <= 0) { timeout = 120; } for (;;) { BLOCK_INTERUPTS; r = symlink(name, lockname); if (r == 0) { *file_locked = 1; UNBLOCK_INTERUPTS; return 0; /* success */ } UNBLOCK_INTERUPTS; if (errno != EEXIST) { file_lock_error(msg, name, "symlink(%s, %s)", name, lockname); fprintf(stderr, "%s", msg); return errno; } counter = 0; for (;;) { sleep(1); r = lstat(lockname, &statb); if (r == -1) { /* * The lock must have just gone away - try * again. */ break; } if ((counter > 5) && (!printed_warning)) { /* Print waiting message after 5 secs */ (void) getcwd(msg, MAXPATHLEN); fprintf(stderr, gettext( "file_lock: file %s is already locked.\n"), name); fprintf(stderr, gettext( "file_lock: will periodically check the " "lockfile %s for two minutes.\n"), lockname); fprintf(stderr, gettext( "Current working directory %s\n"), msg); printed_warning = 1; } if (++counter > timeout ) { /* * Waited enough - return an error.. */ return EEXIST; } } } /* NOTREACHED */ } /* * Format a message telling why the lock could not be created. */ static void file_lock_error(char *msg, char *file, const char *str, char *arg1, char *arg2) { int len, err; char *ptr; sprintf(msg, gettext("Could not lock file `%s'; "), file); len = strlen(msg); sprintf(&msg[len], str, arg1, arg2); strcat(msg, gettext(" failed - ")); err = errno; errno = 0; ptr = strerror(err); if (errno != EINVAL) { strcat(msg, ptr); } else { len = strlen(msg); sprintf(&msg[len], "errno %d", err); } } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1998 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include extern int lstat(const char *path, struct stat *buf); #include #include static int lstat_thunk(char *path) { vroot_result= lstat(path, vroot_args.lstat.buffer); return(vroot_result == 0); } int lstat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot) { vroot_args.lstat.buffer= buffer; translate_with_thunk(path, lstat_thunk, vroot_path, vroot_vroot, rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include extern int mkdir(const char *path, mode_t mode); #include #include static int mkdir_thunk(char *path) { vroot_result= mkdir(path, vroot_args.mkdir.mode); return(vroot_result == 0); } int mkdir_vroot(char *path, int mode, pathpt vroot_path, pathpt vroot_vroot) { vroot_args.mkdir.mode= mode; translate_with_thunk(path, mkdir_thunk, vroot_path, vroot_vroot, rw_write); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1995 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include extern int mount(const char *spec, const char *dir, int mflag, ...); #include #include static int mount_thunk(char *path) { vroot_result= mount(path, vroot_args.mount.name, vroot_args.mount.mode); return(vroot_result == 0); } int mount_vroot(char *target, char *name, int mode, pathpt vroot_path, pathpt vroot_vroot) { vroot_args.mount.name= name; vroot_args.mount.mode= mode; translate_with_thunk(target, mount_thunk, vroot_path, vroot_vroot, rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include extern int open(const char *path, int oflag, ...); #include #include static int open_thunk(char *path) { vroot_result= open(path, vroot_args.open.flags, vroot_args.open.mode); return(vroot_result >= 0); } int open_vroot(char *path, int flags, int mode, pathpt vroot_path, pathpt vroot_vroot) { vroot_args.open.flags= flags; vroot_args.open.mode= mode; translate_with_thunk(path, open_thunk, vroot_path, vroot_vroot, ((flags & (O_CREAT|O_APPEND)) != 0) ? rw_write : rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include extern int readlink(const char *path, void *buf, size_t bufsiz); #include #include static int readlink_thunk(char *path) { vroot_result= readlink(path, vroot_args.readlink.buffer, vroot_args.readlink.buffer_size); return(vroot_result >= 0); } int readlink_vroot(char *path, char *buffer, int buffer_size, pathpt vroot_path, pathpt vroot_vroot) { vroot_args.readlink.buffer= buffer; vroot_args.readlink.buffer_size= buffer_size; translate_with_thunk(path, readlink_thunk, vroot_path, vroot_vroot, rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include #include #include #include #include /* for tmpdir */ static FILE *report_file; static FILE *command_output_fp; static char *target_being_reported_for; static char *search_dir; static char command_output_tmpfile[30]; static int is_path = 0; static char sfile[MAXPATHLEN]; extern "C" { static void (*warning_ptr) (char *, ...) = (void (*) (char *, ...)) NULL; } FILE * get_report_file(void) { return(report_file); } char * get_target_being_reported_for(void) { return(target_being_reported_for); } extern "C" { static void close_report_file(void) { (void)fputs("\n", report_file); (void)fclose(report_file); } } // extern "C" static void clean_up(FILE *nse_depinfo_fp, FILE *merge_fp, char *nse_depinfo_file, char *merge_file, int unlinkf) { fclose(nse_depinfo_fp); fclose(merge_fp); fclose(command_output_fp); unlink(command_output_tmpfile); if (unlinkf) unlink(merge_file); else rename(merge_file, nse_depinfo_file); } /* * Update the file, if necessary. We don't want to rewrite * the file if we don't have to because we don't want the time of the file * to change in that case. */ extern "C" { static void close_file(void) { char line[MAXPATHLEN+2]; char buf[MAXPATHLEN+2]; FILE *nse_depinfo_fp; FILE *merge_fp; char nse_depinfo_file[MAXPATHLEN]; char merge_file[MAXPATHLEN]; char lock_file[MAXPATHLEN]; int err; int len; int changed = 0; int file_locked; fprintf(command_output_fp, "\n"); fclose(command_output_fp); if ((command_output_fp = fopen(command_output_tmpfile, "r")) == NULL) { return; } sprintf(nse_depinfo_file, "%s/%s", search_dir, NSE_DEPINFO); sprintf(merge_file, "%s/.tmp%s.%d", search_dir, NSE_DEPINFO, getpid()); sprintf(lock_file, "%s/%s", search_dir, NSE_DEPINFO_LOCK); err = file_lock(nse_depinfo_file, lock_file, &file_locked, 0); if (err) { if (warning_ptr != (void (*) (char *, ...)) NULL) { (*warning_ptr)(gettext("Couldn't write to %s"), nse_depinfo_file); } unlink(command_output_tmpfile); return; } /* If .nse_depinfo file doesn't exist */ if ((nse_depinfo_fp = fopen(nse_depinfo_file, "r+")) == NULL) { if (is_path) { if ((nse_depinfo_fp = fopen(nse_depinfo_file, "w")) == NULL) { fprintf(stderr, gettext("Cannot open `%s' for writing\n"), nse_depinfo_file); unlink(command_output_tmpfile); unlink(lock_file); return; } while (fgets(line, MAXPATHLEN+2, command_output_fp) != NULL) { fprintf(nse_depinfo_fp, "%s", line); } fclose(command_output_fp); } fclose(nse_depinfo_fp); if (file_locked) { unlink(lock_file); } unlink(command_output_tmpfile); return; } if ((merge_fp = fopen(merge_file, "w")) == NULL) { fprintf(stderr, gettext("Cannot open %s for writing\n"), merge_file); if (file_locked) { unlink(lock_file); } unlink(command_output_tmpfile); return; } len = strlen(sfile); while (fgets(line, MAXPATHLEN+2, nse_depinfo_fp) != NULL) { if (strncmp(line, sfile, len) == 0 && line[len] == ':') { while (fgets(buf, MAXPATHLEN+2, command_output_fp) != NULL) { if (is_path) { fprintf(merge_fp, "%s", buf); if (strcmp(line, buf)) { /* changed */ changed = 1; } } if (buf[strlen(buf)-1] == '\n') { break; } } if (changed || !is_path) { while (fgets(line, MAXPATHLEN, nse_depinfo_fp) != NULL) { fputs(line, merge_fp); } clean_up(nse_depinfo_fp, merge_fp, nse_depinfo_file, merge_file, 0); } else { clean_up(nse_depinfo_fp, merge_fp, nse_depinfo_file, merge_file, 1); } if (file_locked) { unlink(lock_file); } unlink(command_output_tmpfile); return; } /* entry found */ fputs(line, merge_fp); } /* Entry never found. Add it if there is a search path */ if (is_path) { while (fgets(line, MAXPATHLEN+2, command_output_fp) != NULL) { fprintf(nse_depinfo_fp, "%s", line); } } clean_up(nse_depinfo_fp, merge_fp, nse_depinfo_file, merge_file, 1); if (file_locked) { unlink(lock_file); } } } // extern "C" static void report_dep(char *iflag, char *filename) { if (command_output_fp == NULL) { sprintf(command_output_tmpfile, "%s/%s.%d.XXXXXX", tmpdir, NSE_DEPINFO, getpid()); int fd = mkstemp(command_output_tmpfile); if ((fd < 0) || (command_output_fp = fdopen(fd, "w")) == NULL) { return; } if ((search_dir = getenv("NSE_DEP")) == NULL) { return; } atexit(close_file); strcpy(sfile, filename); if (iflag == NULL || *iflag == '\0') { return; } fprintf(command_output_fp, "%s:", sfile); } fprintf(command_output_fp, " "); fprintf(command_output_fp, iflag); if (iflag != NULL) { is_path = 1; } } void report_libdep(char *lib, char *flag) { char *ptr; char filename[MAXPATHLEN]; char *p; if ((p= getenv(SUNPRO_DEPENDENCIES)) == NULL) { return; } ptr = strchr(p, ' '); if(ptr) { sprintf(filename, "%s-%s", ptr+1, flag); is_path = 1; report_dep(lib, filename); } } void report_search_path(char *iflag) { char curdir[MAXPATHLEN]; char *sdir; char *newiflag; char filename[MAXPATHLEN]; char *p, *ptr; if ((sdir = getenv("NSE_DEP")) == NULL) { return; } if ((p= getenv(SUNPRO_DEPENDENCIES)) == NULL) { return; } ptr = strchr(p, ' '); if( ! ptr ) { return; } sprintf(filename, "%s-CPP", ptr+1); getcwd(curdir, sizeof(curdir)); if (strcmp(curdir, sdir) != 0 && strlen(iflag) > 2 && iflag[2] != '/') { /* Makefile must have had an "cd xx; cc ..." */ /* Modify the -I path to be relative to the cd */ newiflag = (char *)malloc(strlen(iflag) + strlen(curdir) + 2); sprintf(newiflag, "-%c%s/%s", iflag[1], curdir, &iflag[2]); report_dep(newiflag, filename); } else { report_dep(iflag, filename); } } void report_dependency(const char *name) { char *filename; char buffer[MAXPATHLEN+1]; char *p; char *p2; char nse_depinfo_file[MAXPATHLEN]; if (report_file == NULL) { if ((filename= getenv(SUNPRO_DEPENDENCIES)) == NULL) { report_file = (FILE *)-1; return; } if (strlen(filename) == 0) { report_file = (FILE *)-1; return; } (void)strcpy(buffer, name); name = buffer; p = strchr(filename, ' '); if(p) { *p= 0; } else { report_file = (FILE *)-1; return; } if ((report_file= fopen(filename, "a")) == NULL) { if ((report_file= fopen(filename, "w")) == NULL) { report_file= (FILE *)-1; return; } } atexit(close_report_file); if ((p2= strchr(p+1, ' ')) != NULL) *p2= 0; target_being_reported_for= (char *)malloc((unsigned)(strlen(p+1)+1)); (void)strcpy(target_being_reported_for, p+1); (void)fputs(p+1, report_file); (void)fputs(":", report_file); *p= ' '; if (p2 != NULL) *p2= ' '; } if (report_file == (FILE *)-1) return; (void)fputs(name, report_file); (void)fputs(" ", report_file); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include extern int rmdir(const char *path); #include #include static int rmdir_thunk(char *path) { vroot_result= rmdir(path); return(vroot_result == 0); } int rmdir_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot) { translate_with_thunk(path, rmdir_thunk, vroot_path, vroot_vroot, rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1994 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include extern char **environ; static short setenv_made_new_vector= 0; char *setenv(char *name, char *value) { char *p= NULL, **q; int length= 0, vl; if ((p= getenv(name)) == NULL) { /* Allocate new vector */ for (q= environ; *q != NULL; q++, length++); q= (char **)malloc((unsigned)(sizeof(char *)*(length+2))); memcpy(((char *)q)+sizeof(char *), (char *)environ, sizeof(char *)*(length+1)); if (setenv_made_new_vector++) free((char *)environ); length= strlen(name); environ= q;} else { /* Find old slot */ length= strlen(name); for (q= environ; *q != NULL; q++) if (!strncmp(*q, name, length)) break;}; vl= strlen(value); if (!p || (length+vl+1 > strlen(p))) *q= p= (char *) malloc((unsigned)(length+vl+2)); else p= *q; (void)strcpy(p, name); p+= length; *p++= '='; (void)strcpy(p, value); return(value); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1998 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include extern int stat(const char *path, struct stat *buf); #include #include static int stat_thunk(char *path) { vroot_result= stat(path, vroot_args.stat.buffer); return(vroot_result == 0); } int stat_vroot(char *path, struct stat *buffer, pathpt vroot_path, pathpt vroot_vroot) { vroot_args.stat.buffer= buffer; translate_with_thunk(path, stat_thunk, vroot_path, vroot_vroot, rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include extern int truncate(const char *path, off_t length); #include #include static int truncate_thunk(char *path) { vroot_result= truncate(path, vroot_args.truncate.length); return(vroot_result == 0); } int truncate_vroot(char *path, int length, pathpt vroot_path, pathpt vroot_vroot) { vroot_args.truncate.length= length; translate_with_thunk(path, truncate_thunk, vroot_path, vroot_vroot, rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include extern int unlink(const char *path); #include #include static int unlink_thunk(char *path) { vroot_result= unlink(path); return(vroot_result == 0); } int unlink_vroot(char *path, pathpt vroot_path, pathpt vroot_vroot) { translate_with_thunk(path, unlink_thunk, vroot_path, vroot_vroot, rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include extern int utimes(char *file, struct timeval *tvp); #include #include static int utimes_thunk(char *path) { vroot_result= utimes(path, vroot_args.utimes.time); return(vroot_result == 0); } int utimes_vroot(char *path, struct timeval *time, pathpt vroot_path, pathpt vroot_vroot) { vroot_args.utimes.time= time; translate_with_thunk(path, utimes_thunk, vroot_path, vroot_vroot, rw_read); return(vroot_result); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include #include typedef struct { short init; pathpt vector; const char *env_var; } vroot_patht; typedef struct { vroot_patht vroot; vroot_patht path; char full_path[MAXPATHLEN+1]; char *vroot_start; char *path_start; char *filename_start; int scan_vroot_first; int cpp_style_path; } vroot_datat, *vroot_datapt; static vroot_datat vroot_data= { { 0, NULL, "VIRTUAL_ROOT"}, { 0, NULL, "PATH"}, "", NULL, NULL, NULL, 0, 1}; void add_dir_to_path(const char *path, pathpt *pointer, int position) { int size= 0; int length; char *name; pathcellpt p; pathpt new_path; if (*pointer != NULL) { for (p= &((*pointer)[0]); p->path != NULL; p++, size++); if (position < 0) position= size;} else if (position < 0) position= 0; if (position >= size) { new_path= (pathpt)calloc((unsigned)(position+2), sizeof(pathcellt)); if (*pointer != NULL) { memcpy((char *)new_path,(char *)(*pointer), size*sizeof(pathcellt)); free((char *)(*pointer));}; *pointer= new_path;}; length= strlen(path); name= (char *)malloc((unsigned)(length+1)); (void)strcpy(name, path); if ((*pointer)[position].path != NULL) free((*pointer)[position].path); (*pointer)[position].path= name; (*pointer)[position].length= length; } pathpt parse_path_string(char *string, int remove_slash) { char *p; pathpt result= NULL; if (string != NULL) for (; 1; string= p+1) { if (p= strchr(string, ':')) *p= 0; if ((remove_slash == 1) && !strcmp(string, "/")) add_dir_to_path("", &result, -1); else add_dir_to_path(string, &result, -1); if (p) *p= ':'; else return(result);}; return((pathpt)NULL); } const char * get_vroot_name(void) { return(vroot_data.vroot.env_var); } const char * get_path_name(void) { return(vroot_data.path.env_var); } void flush_path_cache(void) { vroot_data.path.init= 0; } void flush_vroot_cache(void) { vroot_data.vroot.init= 0; } void scan_path_first(void) { vroot_data.scan_vroot_first= 0; } void scan_vroot_first(void) { vroot_data.scan_vroot_first= 1; } void set_path_style(int style) { vroot_data.cpp_style_path= style; } char * get_vroot_path(char **vroot, char **path, char **filename) { if (vroot != NULL) { if ((*vroot= vroot_data.vroot_start) == NULL) if ((*vroot= vroot_data.path_start) == NULL) *vroot= vroot_data.filename_start;}; if (path != NULL) { if ((*path= vroot_data.path_start) == NULL) *path= vroot_data.filename_start;}; if (filename != NULL) *filename= vroot_data.filename_start; return(vroot_data.full_path); } void translate_with_thunk(char *filename, int (*thunk) (char *), pathpt path_vector, pathpt vroot_vector, rwt rw) { pathcellt *vp; pathcellt *pp; pathcellt *pp1; char *p; int flags[256]; /* Setup path to use */ if (rw == rw_write) pp1= NULL; /* Do not use path when writing */ else { if (path_vector == VROOT_DEFAULT) { if (!vroot_data.path.init) { vroot_data.path.init= 1; vroot_data.path.vector= parse_path_string(getenv(vroot_data.path.env_var), 0);}; path_vector= vroot_data.path.vector;}; pp1= path_vector == NULL ? NULL : &(path_vector)[0];}; /* Setup vroot to use */ if (vroot_vector == VROOT_DEFAULT) { if (!vroot_data.vroot.init) { vroot_data.vroot.init= 1; vroot_data.vroot.vector= parse_path_string(getenv(vroot_data.vroot.env_var), 1);}; vroot_vector= vroot_data.vroot.vector;}; vp= vroot_vector == NULL ? NULL : &(vroot_vector)[0]; /* Setup to remember pieces */ vroot_data.vroot_start= NULL; vroot_data.path_start= NULL; vroot_data.filename_start= NULL; int flen = strlen(filename); if(flen >= MAXPATHLEN) { errno = ENAMETOOLONG; return; } switch ((vp ?1:0) + (pp1 ? 2:0)) { case 0: /* No path. No vroot. */ use_name: (void)strcpy(vroot_data.full_path, filename); vroot_data.filename_start= vroot_data.full_path; (void)(*thunk)(vroot_data.full_path); return; case 1: /* No path. Vroot */ if (filename[0] != '/') goto use_name; for (; vp->path != NULL; vp++) { if((1 + flen + vp->length) >= MAXPATHLEN) { errno = ENAMETOOLONG; continue; } p= vroot_data.full_path; (void)strcpy(vroot_data.vroot_start= p, vp->path); p+= vp->length; (void)strcpy(vroot_data.filename_start= p, filename); if ((*thunk)(vroot_data.full_path)) return;}; (void)strcpy(vroot_data.full_path, filename); return; case 2: /* Path. No vroot. */ if (vroot_data.cpp_style_path) { if (filename[0] == '/') goto use_name; } else { if (strchr(filename, '/') != NULL) goto use_name; }; for (; pp1->path != NULL; pp1++) { p= vroot_data.full_path; if((1 + flen + pp1->length) >= MAXPATHLEN) { errno = ENAMETOOLONG; continue; } if (vroot_data.cpp_style_path) { (void)strcpy(vroot_data.path_start= p, pp1->path); p+= pp1->length; *p++= '/'; } else { if (pp1->length != 0) { (void)strcpy(vroot_data.path_start= p, pp1->path); p+= pp1->length; *p++= '/'; }; }; (void)strcpy(vroot_data.filename_start= p, filename); if ((*thunk)(vroot_data.full_path)) return;}; (void)strcpy(vroot_data.full_path, filename); return; case 3: { /* Path. Vroot. */ int *rel_path, path_len= 1; if (vroot_data.scan_vroot_first == 0) { for (pp= pp1; pp->path != NULL; pp++) path_len++; rel_path= flags; for (path_len-= 2; path_len >= 0; path_len--) rel_path[path_len]= 0; for (; vp->path != NULL; vp++) for (pp= pp1, path_len= 0; pp->path != NULL; pp++, path_len++) { int len = 0; if (rel_path[path_len] == 1) continue; if (pp->path[0] != '/') rel_path[path_len]= 1; p= vroot_data.full_path; if ((filename[0] == '/') || (pp->path[0] == '/')) { if(vp->length >= MAXPATHLEN) { errno = ENAMETOOLONG; continue; } (void)strcpy(vroot_data.vroot_start= p, vp->path); p+= vp->length; len += vp->length; }; if (vroot_data.cpp_style_path) { if (filename[0] != '/') { if(1 + len + pp->length >= MAXPATHLEN) { errno = ENAMETOOLONG; continue; } (void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length; *p++= '/'; len += 1 + pp->length; }; } else { if (strchr(filename, '/') == NULL) { if (pp->length != 0) { if(1 + len + pp->length >= MAXPATHLEN) { errno = ENAMETOOLONG; continue; } (void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length; *p++= '/'; len += 1 + pp->length; } } }; (void)strcpy(vroot_data.filename_start= p, filename); if ((*thunk)(vroot_data.full_path)) return;};} else { pathcellt *vp1= vp; for (pp= pp1, path_len= 0; pp->path != NULL; pp++, path_len++) for (vp= vp1; vp->path != NULL; vp++) { int len = 0; p= vroot_data.full_path; if ((filename[0] == '/') || (pp->path[0] == '/')) { if(vp->length >= MAXPATHLEN) { errno = ENAMETOOLONG; continue; } (void)strcpy(vroot_data.vroot_start= p, vp->path); p+= vp->length; len += vp->length; } if (vroot_data.cpp_style_path) { if (filename[0] != '/') { if(1 + len + pp->length >= MAXPATHLEN) { errno = ENAMETOOLONG; continue; } (void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length; *p++= '/'; len += 1 + pp->length; } } else { if (strchr(filename, '/') == NULL) { if(1 + len + pp->length >= MAXPATHLEN) { errno = ENAMETOOLONG; continue; } (void)strcpy(vroot_data.path_start= p, pp->path); p+= pp->length; *p++= '/'; len += 1 + pp->length; } } (void)strcpy(vroot_data.filename_start= p, filename); if ((*thunk)(vroot_data.full_path)) return;};}; (void)strcpy(vroot_data.full_path, filename); return;};}; }