int load_words (char *fname) { FILE *fp = NULL; UINT32 flen; UINT8 *mem = NULL; char *path = NULL; words = NULL; path = fixpath (NO_GAMEDIR, fname); if ((fp = fopen(path, "rb")) == NULL) { report ("Warning: can't open %s\n", path); return err_OK /*err_BadFileOpen*/; } report ("Loading dictionary: %s\n", path); fseek (fp, 0, SEEK_END); flen = ftell (fp); words_flen = flen; fseek (fp, 0, SEEK_SET); if ((mem = (UINT8*)calloc(1, flen + 32)) == NULL) { fclose (fp); return err_NotEnoughMemory; } fread (mem, 1, flen, fp); fclose (fp); words = mem; return err_OK; }
int agi_v3_detect_game (char *gn) { int ec = err_Unk; char x[MAX_PATH], *xname, *path; int l; _D ("(\"%s\")", gn); strncpy (game.dir, gn, MAX_PATH); strcpy (x, "*vol.0"); path = fixpath (GAMEDIR, x); _D (_D_WARN "path = %s", path); if (file_isthere (path)) { _D(_D_WARN "getting xname for path = %s", path); xname = file_name (path); /* remove the DIR from xname */ l = strlen (xname); if (l >= 5) l -= 5; xname[l] = 0; strncpy (game.name, xname, 8); _D (_D_WARN "game.name = %s", game.name); agi_v3.int_version = 0x3149; /* setup for 3.002.149 */ ec = v3id_game(); } else { _D (_D_CRIT "not found"); ec = err_InvalidAGIFile; } return ec; }
void fixpathlist(std::string& list) { std::string old(std::move(list)); list = ""; size_t at = 0; size_t to = old.find_first_of(':', 0); while (to != std::string::npos) { std::string sub(old.substr(at, to-at)); fixpath(sub); list.append(std::move(sub)); list.append(1, ':'); at = to+1; to = old.find_first_of(':', at); } std::string sub(old.substr(at, to-at)); fixpath(sub); list.append(std::move(sub)); }
int stream_unlink(const char *path) { int rc; drop_privilege(); rc = (unlink(fixpath(path))) ? -errno : 0; regain_privilege(); return rc; }
int stream_getattr(const char *path, struct stat *st) { int rc; drop_privilege(); rc = (stat(fixpath(path), st)) ? -errno : 0; regain_privilege(); return rc; }
/* Open a zip-compatible archive and extract all files * into the specified directory (which is assumed to exist) */ BOOL unzip_archive (char *dirname, char *data, DWORD size, NOTIFYPROC notify) { int n; char pathname[MAX_PATH]; char *new_part; /* read the end of central directory record */ struct eof_cdir *pe = (struct eof_cdir *)&data[size - sizeof (struct eof_cdir)]; int arc_start = size - sizeof (struct eof_cdir) - pe->nBytesCDir - pe->ofsCDir; /* set position to start of central directory */ int pos = arc_start + pe->ofsCDir; /* make sure this is a zip file */ if (pe->tag != 0x06054b50) return FALSE; /* Loop through the central directory, reading all entries */ for (n = 0; n < pe->nTotalCDir; ++n) { char *fname; char *pcomp; char *dst; struct cdir *pcdir = (struct cdir *)&data[pos]; struct fhdr *pfhdr = (struct fhdr *)&data[pcdir->ofs_local_header + arc_start]; if (pcdir->tag != 0x02014b50) return FALSE; if (pfhdr->tag != 0x04034b50) return FALSE; pos += sizeof (struct cdir); fname = (char *)&data[pos]; /* This is not null terminated! */ pos += pcdir->fname_length + pcdir->extra_length + pcdir->comment_length; pcomp = &data[pcdir->ofs_local_header + sizeof (struct fhdr) + arc_start + pfhdr->fname_length + pfhdr->extra_length]; strcpy (pathname, dirname); strcat (pathname, "\\"); new_part = &pathname[lstrlen (pathname)]; strncat (pathname, fname, pfhdr->fname_length); fixpath (pathname); if (pathname[strlen(pathname)-1] != '\\') { /* * The local file header (pfhdr) does not always contain * the compressed and uncompressed sizes of the data * depending on bit 3 of the flags field. * So it seems better to use the data from the * central directory (pcdir). */ dst = map_new_file (0, pathname, new_part, pcdir->uncomp_size, pcdir->last_mod_file_date, pcdir->last_mod_file_time, notify); if (dst) { if (!extract_file (dst, pcomp, pfhdr->method, pcdir->comp_size, pcdir->uncomp_size, notify)) return FALSE; } /* else ??? */ } if (notify) notify (NUM_FILES, new_part, (int)pe->nTotalCDir, (int)n+1); } return TRUE; }
int _open_r(struct _reent *reent, const char *path, int flags, int mode) { wchar_t wpath[MAX_PATH]; char pathbuf[MAX_PATH]; HANDLE hnd = NULL; DWORD fileaccess; DWORD fileshare; DWORD filecreate; DWORD fileattrib; void *cxt; int fd; WCETRACE(WCE_IO, "open(%s, %x, %o)", path, flags, mode); _initfds(); if (!strncmp("fifo", path, 4)) { fd = _assignfd(IO_FILE_TYPE_FIFO, NULL, 0); if (fd < 0) { errno = ENMFILE; return(-1); } _fdtab[fd].devops = _fifo_devops; _fdtab[fd].cxt = cxt = _fifo_alloc(); if ((_fdtab[fd].fd = _fdtab[fd].devops->open_r(reent, path, flags, mode, cxt)) == -1) { WCETRACE(WCE_IO, "FIFO open fails, errno %d", errno); _fdtab[fd].fd = -1; return(-1); } } else if(!strncmp(path, "nul", 3) || !strncmp(path, "nul:", 4) || !strncmp(path, "null:", 5) || !strncmp(path, "/dev/nul", 8) || !strncmp(path, "/dev/null", 9)) { fd = _assignfd(IO_FILE_TYPE_NULL, (HANDLE) -1, 0); if (fd < 0) { errno = ENMFILE; return(-1); } _fdtab[fd].devops = NULL; _fdtab[fd].cxt = NULL; } else { if (strlen(path) >= MAX_PATH) { WCETRACE(WCE_IO, "open fails, invalid path\n"); return(-1); } fixpath(path, pathbuf); mbstowcs(wpath, pathbuf, strlen(pathbuf) + 1); fileshare = FILE_SHARE_READ|FILE_SHARE_WRITE; fileattrib = FILE_ATTRIBUTE_NORMAL; switch (flags & (O_RDONLY | O_WRONLY | O_RDWR)) { case O_RDONLY: /* read access */ fileaccess = GENERIC_READ; break; case O_WRONLY: /* write access */ fileaccess = GENERIC_WRITE; break; case O_RDWR: /* read and write access */ fileaccess = GENERIC_READ | GENERIC_WRITE; break; default: /* error, bad flags */ errno = EINVAL; return -1; } switch (flags & (O_CREAT | O_EXCL | O_TRUNC)) { case 0: case O_EXCL: /* ignore EXCL w/o CREAT */ filecreate = OPEN_EXISTING; break; case O_CREAT: filecreate = OPEN_ALWAYS; break; case O_CREAT | O_EXCL: case O_CREAT | O_TRUNC | O_EXCL: filecreate = CREATE_NEW; break; case O_TRUNC: case O_TRUNC | O_EXCL: /* ignore EXCL w/o CREAT */ filecreate = TRUNCATE_EXISTING; break; case O_CREAT | O_TRUNC: filecreate = CREATE_ALWAYS; break; default: /* this can't happen ... all cases are covered */ errno = EINVAL; return(-1); } if ((hnd = _CreateFileW(wpath, fileaccess, fileshare, NULL, filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE) { errno = _winerr2errno(GetLastError()); WCETRACE(WCE_IO, "_CreateFile(%s): errno=%d oserr=%d\n", pathbuf, errno, GetLastError()); return(-1); } fd = _assignfd(IO_FILE_TYPE_FILE, hnd, 0); if (fd < 0) { errno = ENMFILE; return(-1); } _fdtab[fd].devops = NULL; _fdtab[fd].cxt = NULL; if (flags & O_APPEND) { _SetFilePointer(hnd, 0, NULL, FILE_END); } } WCETRACE(WCE_IO, "open returns %d fd %d cxt %p (hnd %x)", fd, _fdtab[fd].fd, cxt, hnd); return fd; }
static int mkpath( char *pathname, int trace) { char *base; struct stat st; int ch, ididit; if (pathname == NULL) { fprintf(stderr, "%s: NULL path argument\n", progname); return(1); } pathname = (char *)strdup(pathname); if (pathname == NULL) fprintf(stderr, "%s: strdup failed\n", progname); base = fixpath(pathname); if (base == NULL || base == pathname) { fprintf(stderr, "%s: %s must have an imbedded '/' character\n", progname, pathname); return(1); } *base = '\0'; base = pathname; if (*base == '/') base++; if (*base == '\0') { fprintf(stderr, "%s: illegal pathname %s\n", progname, pathname); return(1); } for (;;) { /* find end of this component */ while (*base != '\0' && *base != '/') base++; /* create path so far, if necessary */ ch = *base; *base = '\0'; if (stat(pathname, &st) < 0) { if (mkdir(pathname, 0777) < 0) { if (errno != EEXIST) { fprintf(stderr, "%s: unable to create directory %s: %s\n", progname, pathname, strerror(errno)); return(1); } ididit = FALSE; } else ididit = TRUE; if (stat(pathname, &st) < 0) { fprintf(stderr, "%s: unable to stat directory %s: %s\n", progname, pathname, strerror(errno)); return(1); } if (ididit && trace) fprintf(stderr, "%s: created directory\n", pathname); } else if ((st.st_mode&S_IFMT) != S_IFDIR) { fprintf(stderr, "%s: %s is not a directory (mode %#o)\n", progname, pathname, (st.st_mode&S_IFMT)); return(1); } if (ch == '\0') break; *base++ = ch; } return(0); }
int main(int argc, char *argv[]) { FILE *fp; char *abi_comp_ptr; char *abi_sym_ptr; char *p; char *prog_full_name = NULL; char *pt; char *value; char *vfstab_file = NULL; char *zoneName = (char *)NULL; char cmdbin[PATH_MAX]; char param[MAX_PKG_PARAM_LENGTH]; char path[PATH_MAX]; char script[PATH_MAX]; int c; int err; int fd; int i; int map_client = 1; int n; int nodelete = 0; /* do not delete file or run scripts */ int pkgrmremote = 0; /* dont remove remote objects */ struct sigaction nact; struct sigaction oact; PKGserver pkgserver = NULL; VFP_T *tmpfp; /* reset contents of all default paths */ (void) memset(cmdbin, '\0', sizeof (cmdbin)); /* initialize locale environment */ (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); /* initialize program name */ prog_full_name = argv[0]; (void) set_prog_name(argv[0]); /* tell spmi zones interface how to access package output functions */ z_set_output_functions(echo, echoDebug, progerr); /* exit if not root */ if (getuid()) { progerr(ERR_NOT_ROOT, get_prog_name()); exit(1); /* NOTREACHED */ } /* Read PKG_INSTALL_ROOT from the environment, if it's there. */ if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) { progerr(ERR_ROOT_SET); exit(1); } pkgserversetmode(DEFAULTMODE); /* parse command line options */ while ((c = getopt(argc, argv, "?Aa:b:FMN:nO:oR:V:vy")) != EOF) { switch (c) { /* * Same as pkgrm: Allow admin to remove package objects from * a shared area from a reference client. */ case 'A': pkgrmremote++; break; /* * Same as pkgrm: Use the installation * administration file, admin, in place of the * default admin file. pkgrm first looks in the * current working directory for the administration * file. If the specified administration file is not * in the current working directory, pkgrm looks in * the /var/sadm/install/admin directory for the * administration file. */ case 'a': admnfile = flex_device(optarg, 0); break; /* * Same as pkgrm: location where package executables * can be found - default is /usr/sadm/install/bin. */ case 'b': if (!path_valid(optarg)) { progerr(ERR_PATH, optarg); exit(1); } if (isdir(optarg) != 0) { char *p = strerror(errno); progerr(ERR_CANNOT_USE_DIR, optarg, p); exit(1); } (void) strlcpy(cmdbin, optarg, sizeof (cmdbin)); break; /* * Same as pkgrm: suppresses the removal of any * files and any class action scripts, and suppresses * the running of any class action scripts. The * package files remain but the package looks like it * is not installed. This is mainly for use by the * upgrade process. */ case 'F': nodelete++; break; /* * Same as pkgrm: Instruct pkgrm not to use the * $root_path/etc/vfstab file for determining the * client's mount points. This option assumes the * mount points are correct on the server and it * behaves consistently with Solaris 2.5 and earlier * releases. */ case 'M': map_client = 0; break; /* * Different from pkgrm: specify program name to use * for messages. */ case 'N': (void) set_prog_name(optarg); break; /* * Same as pkgrm: package removal occurs in * non-interactive mode. Suppress output of the list of * removed files. The default mode is interactive. */ case 'n': nointeract++; (void) echoSetFlag(B_FALSE); break; /* * Almost same as pkgrm: the -O option allows the behavior * of the package tools to be modified. Recognized options: * -> debug * ---> enable debugging output * -> preremovecheck * ---> perform a "pre removal" check of the specified * ---> package - suppress all regular output and cause a * ---> series of one or more "name=value" pair format lines * ---> to be output that describes the "removability" of * ---> the specified package * -> enable-hollow-package-support * --> Enable hollow package support. When specified, for any * --> package that has SUNW_PKG_HOLLOW=true: * --> Do not calculate and verify package size against target * --> Do not run any package procedure or class action scripts * --> Do not create or remove any target directories * --> Do not perform any script locking * --> Do not install or uninstall any components of any package * --> Do not output any status or database update messages */ case 'O': for (p = strtok(optarg, ","); p != (char *)NULL; p = strtok(NULL, ",")) { /* process debug option */ if (strcmp(p, "debug") == 0) { /* set debug flag/enable debug output */ debugFlag = B_TRUE; (void) echoDebugSetFlag(debugFlag); /* debug info on arguments to pkgadd */ for (n = 0; n < argc && argv[n]; n++) { echoDebug(DBG_ARG, n, argv[n]); } continue; } /* process enable-hollow-package-support opt */ if (strcmp(p, "enable-hollow-package-support") == 0) { set_depend_pkginfo_DB(B_TRUE); continue; } /* process preremovecheck option */ if (strcmp(p, "preremovecheck") == 0) { preremoveCheck = B_TRUE; nointeract++; /* -n */ nodelete++; /* -F */ quitSetSilentExit(B_TRUE); continue; } /* process addzonename option */ if (strcmp(p, "addzonename") == 0) { zoneName = z_get_zonename(); quitSetZoneName(zoneName); continue; } /* process parent-zone-name option */ if (strncmp(p, PARENTZONENAME, PARENTZONENAME_LEN) == 0) { parentZoneName = p+PARENTZONENAME_LEN; continue; } /* process parent-zone-type option */ if (strncmp(p, PARENTZONETYPE, PARENTZONETYPE_LEN) == 0) { parentZoneType = p+PARENTZONETYPE_LEN; continue; } if (strncmp(p, PKGSERV_MODE, PKGSERV_MODE_LEN) == 0) { pkgserversetmode(pkgparsemode(p + PKGSERV_MODE_LEN)); continue; } /* option not recognized - issue warning */ progerr(ERR_INVALID_O_OPTION, p); continue; } break; /* * Different from pkgrm: This is an old non-ABI package */ case 'o': script_in = PROC_XSTDIN; break; /* * Same as pkgrm: defines the full path name of a * directory to use as the root_path. All files, * including package system information files, are * relocated to a directory tree starting in the * specified root_path. */ case 'R': if (!set_inst_root(optarg)) { progerr(ERR_ROOT_CMD); exit(1); } break; /* * Same as pkgrm: allow admin to establish the client * filesystem using a vfstab-like file of stable format. */ case 'V': vfstab_file = flex_device(optarg, 2); map_client = 1; break; /* * Same as pkgrm: trace all of the scripts that * get executed by pkgrm, located in the * pkginst/install directory. This option is used for * debugging the procedural and non-procedural * scripts. */ case 'v': pkgverbose++; break; /* * Different from pkgrm: process this package using * old non-ABI symlinks */ case 'y': set_nonABI_symlinks(); break; default: usage(); /*NOTREACHED*/ /* * Although usage() calls a noreturn function, * needed to add return (1); so that main() would * pass compilation checks. The statement below * should never be executed. */ return (1); } } /* * ******************************************************************** * validate command line options * ******************************************************************** */ (void) echoDebugSetFlag(debugFlag); (void) log_set_verbose(debugFlag); if (z_running_in_global_zone()) { echoDebug(DBG_ENTRY_IN_GZ, prog_full_name); } else { echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(), z_get_zonename()); } /* establish cmdbin path */ if (cmdbin[0] == '\0') { (void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin)); } /* Read the mount table */ if (get_mntinfo(map_client, vfstab_file)) { quit(99); } /* * This function defines the standard /var/... directories used later * to construct the paths to the various databases. */ set_PKGpaths(get_inst_root()); /* * If this is being removed from a client whose /var filesystem is * mounted in some odd way, remap the administrative paths to the * real filesystem. This could be avoided by simply mounting up the * client now; but we aren't yet to the point in the process where * modification of the filesystem is permitted. */ if (is_an_inst_root()) { int fsys_value; fsys_value = fsys(get_PKGLOC()); if (use_srvr_map_n(fsys_value)) set_PKGLOC(server_map(get_PKGLOC(), fsys_value)); fsys_value = fsys(get_PKGADM()); if (use_srvr_map_n(fsys_value)) set_PKGADM(server_map(get_PKGADM(), fsys_value)); } else { pkgrmremote = 0; /* Makes no sense on local host. */ } /* * hook SIGINT and SIGHUP interrupts into quit.c's trap handler */ /* hold SIGINT/SIGHUP interrupts */ (void) sighold(SIGHUP); (void) sighold(SIGINT); /* connect quit.c:trap() to SIGINT */ nact.sa_handler = quitGetTrapHandler(); nact.sa_flags = SA_RESTART; (void) sigemptyset(&nact.sa_mask); (void) sigaction(SIGINT, &nact, &oact); /* connect quit.c:trap() to SIGHUP */ nact.sa_handler = quitGetTrapHandler(); nact.sa_flags = SA_RESTART; (void) sigemptyset(&nact.sa_mask); (void) sigaction(SIGHUP, &nact, &oact); /* release hold on signals */ (void) sigrelse(SIGHUP); (void) sigrelse(SIGINT); pkginst = argv[optind++]; if (optind != argc) { usage(); } /* validate package software database (contents) file */ if (vcfile() == 0) { quit(99); } /* * Acquire the package lock - currently at "remove initialization" */ if (!lockinst(get_prog_name(), pkginst, "remove-initial")) { quit(99); } /* establish temporary directory to use */ tmpdir = getenv("TMPDIR"); if (tmpdir == NULL) { tmpdir = P_tmpdir; } echoDebug(DBG_PKGREMOVE_TMPDIR, tmpdir); /* * Initialize installation admin parameters by reading * the adminfile. */ echoDebug(DBG_PKGREMOVE_ADMINFILE, admnfile ? admnfile : ""); setadminFile(admnfile); /* * about to perform first operation that could be modified by the * preremove check option - if preremove check is selected (that is, * only gathering dependencies), then output a debug message to * indicate that the check is beginning. Also turn echo() output * off and set various other flags. */ if (preremoveCheck == B_TRUE) { (void) echoSetFlag(B_FALSE); echoDebug(DBG_PKGREMOVE_PRERMCHK, pkginst ? pkginst : "", zoneName ? zoneName : "global"); rcksetPreremoveCheck(B_TRUE); rcksetZoneName(zoneName); } (void) snprintf(pkgloc, sizeof (pkgloc), "%s/%s", get_PKGLOC(), pkginst); (void) snprintf(pkgbin, sizeof (pkgbin), "%s/install", pkgloc); (void) snprintf(rlockfile, sizeof (rlockfile), "%s/!R-Lock!", pkgloc); if (chdir(pkgbin)) { progerr(ERR_CHDIR, pkgbin); quit(99); } echo(MSG_PREREMOVE_REMINST, pkginst); /* * if a lock file is present, then a previous attempt to remove this * package may have been unsuccessful. */ if (access(rlockfile, F_OK) == 0) { echo(ERR_UNSUCC); echoDebug(DBG_PKGINSTALL_HAS_LOCKFILE, pkginst, rlockfile, zoneName ? zoneName : "global"); } /* * Process all parameters from the pkginfo file * and place them in the execution environment */ /* Add DB retreival of the pkginfo parameters here */ (void) snprintf(path, sizeof (path), "%s/pkginfo", pkgloc); if ((fp = fopen(path, "r")) == NULL) { progerr(ERR_PKGINFO, path); quit(99); } /* Mount up the client if necessary. */ if (map_client && !mount_client()) { logerr(MSG_MANMOUNT); } /* Get mount point of client */ client_mntdir = getenv("CLIENT_MNTDIR"); getuserlocale(); /* * current environment has been read; clear environment out * so putparam() can be used to populate the new environment * to be passed to any executables/scripts. */ environ = NULL; if (nonABI_symlinks()) { putparam("PKG_NONABI_SYMLINKS", "TRUE"); } /* * read the pkginfo file and fix any PKGSAV path - the correct * install_root will be prepended to the existing path. */ param[0] = '\0'; while (value = fpkgparam(fp, param)) { int validx = 0; char *newvalue; /* strip out any setting of PATH */ if (strcmp(param, "PATH") == 0) { free(value); param[0] = '\0'; continue; } /* if not PKGSAV then write out unchanged */ if (strcmp(param, "PKGSAV") != 0) { putparam(param, value); free(value); param[0] = '\0'; continue; } /* * PKGSAV parameter found - interpret the directory: * If in host:path format or marked with the leading "//", * then there is no client-relative translation - take it * literally later rather than use fixpath(). */ if (strstr(value, ":/")) { /* no modification needed */ validx = 0; } else if (strstr(value, "//") == value) { validx = 1; } else if (is_an_inst_root()) { /* This PKGSAV needs to be made client-relative. */ newvalue = fixpath(value); free(value); value = newvalue; } putparam(param, value+validx); free(value); param[0] = '\0'; } (void) fclose(fp); /* write parent condition information to environment */ putConditionInfo(parentZoneName, parentZoneType); putuserlocale(); /* * Now do all the various setups based on ABI compliance */ /* Read the environment provided by the pkginfo file */ abi_comp_ptr = getenv("NONABI_SCRIPTS"); /* if not ABI compliant set global flag */ abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS"); if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0) { set_nonABI_symlinks(); } /* * If pkginfo says it's not compliant then set non_abi_scripts. */ if (abi_comp_ptr && strncmp(abi_comp_ptr, "TRUE", 4) == 0) { script_in = PROC_XSTDIN; } /* * Since this is a removal, we can tell whether it's absolute or * not from the resident pkginfo file read above. */ if ((err = set_basedirs((getenv("BASEDIR") != NULL), adm.basedir, pkginst, nointeract)) != 0) { quit(err); } /* * See if were are removing a package that only wants to update * the database or only remove files associated with CAS's. We * only check the PKG_HOLLOW_VARIABLE variable if told to do so by * the caller. */ if (is_depend_pkginfo_DB()) { pt = getenv(PKG_HOLLOW_VARIABLE); if ((pt != NULL) && (strncasecmp(pt, "true", 4) == 0)) { echoDebug(DBG_PKGREMOVE_HOLLOW_ENABLED); /* * this is a hollow package and hollow package support * is enabled -- override admin settings to suppress * checks that do not make sense since no scripts will * be executed and no files will be removed. */ setadminSetting("conflict", "nocheck"); setadminSetting("setuid", "nocheck"); setadminSetting("action", "nocheck"); setadminSetting("partial", "nocheck"); setadminSetting("space", "nocheck"); setadminSetting("authentication", "nocheck"); } else { echoDebug(DBG_PKGREMOVE_HOLLOW_DISABLED); set_depend_pkginfo_DB(B_FALSE); } } put_path_params(); /* If client mount point, add it to pkgremove environment */ if (client_mntdir != NULL) { putparam("CLIENT_MNTDIR", client_mntdir); } /* Establish the class list and the class attributes. */ if ((value = getenv("CLASSES")) != NULL) { cl_sets(qstrdup(value)); } else { progerr(ERR_CLASSES, path); quit(99); } /* establish path and tmpdir */ if (cmdbin[0] == '\0') { (void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin)); } (void) snprintf(path, sizeof (path), "%s:%s", DEFPATH, cmdbin); putparam("PATH", path); putparam("TMPDIR", tmpdir); /* * Check ulimit requirement (provided in pkginfo). The purpose of * this limit is to terminate pathological file growth resulting from * file edits in scripts. It does not apply to files in the pkgmap * and it does not apply to any database files manipulated by the * installation service. */ if (value = getenv("ULIMIT")) { if (assign_ulimit(value) == -1) { progerr(ERR_BADULIMIT, value); warnflag++; } putparam("PKG_ULIMIT", "TRUE"); } /* * If only gathering dependencies, check and output status of all * remaining dependencies and exit. */ if (preremoveCheck == B_TRUE) { /* * make sure current runlevel is appropriate */ (void) fprintf(stdout, "rckrunlevel=%d\n", rckrunlevel()); /* * determine if any packaging scripts provided with * this package will execute as a priviledged user */ (void) fprintf(stdout, "rckpriv=%d\n", rckpriv()); /* * verify package dependencies */ (void) fprintf(stdout, "rckdepend=%d\n", rckdepend()); /* * ****** preremove check done - exit ****** */ echoDebug(DBG_PKGREMOVE_PRERMCHK_OK); quit(0); /*NOTREACHED*/ } /* * Not gathering dependencies only, proceed to check dependencies * and continue with the package removal operation. */ /* * make sure current runlevel is appropriate */ n = rckrunlevel(); if (n != 0) { quit(n); /* NOTREACHED */ } /* * determine if any packaging scripts provided with * this package will execute as a priviledged user */ n = rckpriv(); if (n != 0) { quit(n); /* NOTREACHED */ } /* * verify package dependencies */ n = rckdepend(); if (n != 0) { quit(n); /* NOTREACHED */ } /* * ********************************************************************* * the actual removal of the package begins here * ********************************************************************* */ /* * create lockfile to indicate start of removal */ started++; if ((fd = open(rlockfile, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { progerr(ERR_LOCKFILE, rlockfile); quit(99); } else { (void) close(fd); } if (zoneName == (char *)NULL) { echo(MSG_PKGREMOVE_PROCPKG_GZ); echoDebug(DBG_PKGREMOVE_PROCPKG_GZ, pkginst, rlockfile); } else { echo(MSG_PKGREMOVE_PROCPKG_LZ, zoneName); echoDebug(DBG_PKGREMOVE_PROCPKG_LZ, pkginst, rlockfile, zoneName); } if (delmap(0, pkginst, &pkgserver, &tmpfp) != 0) { progerr(ERR_DB_QUERY, pkginst); quit(99); } /* * Run a preremove script if one is provided by the package. * Don't execute preremove script if only updating the DB. * Don't execute preremove script if files are not being deleted. */ /* update the lock - at the preremove script */ lockupd("preremove"); /* execute preremove script if one is provided */ (void) snprintf(script, sizeof (script), "%s/preremove", pkgbin); if (access(script, F_OK) != 0) { /* no script present */ echoDebug(DBG_PKGREMOVE_POC_NONE, pkginst, zoneName ? zoneName : "global"); } else if (nodelete) { /* not deleting files: skip preremove script */ echoDebug(DBG_PKGREMOVE_POC_NODEL, pkginst, script, zoneName ? zoneName : "global"); } else if (is_depend_pkginfo_DB()) { /* updating db only: skip preremove script */ echoDebug(DBG_PKGREMOVE_POC_DBUPD, pkginst, script, zoneName ? zoneName : "global"); } else { /* script present and ok to run: run the script */ set_ulimit("preremove", ERR_PREREMOVE); if (zoneName == (char *)NULL) { echo(MSG_PKGREMOVE_EXEPOC_GZ); echoDebug(DBG_PKGREMOVE_EXEPOC_GZ, pkginst, script); } else { echo(MSG_PKGREMOVE_EXEPOC_LZ, zoneName); echoDebug(DBG_PKGREMOVE_EXEPOC_LZ, pkginst, script, zoneName); } putparam("PKG_PROC_SCRIPT", "preremove"); if (pkgverbose) { ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER, PROC_GRP, SHELL, "-x", script, NULL), ERR_PREREMOVE); } else { ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER, PROC_GRP, SHELL, script, NULL), ERR_PREREMOVE); } clr_ulimit(); } /* update the lock - doing removal */ lockupd("remove"); /* * Remove all components belonging to this package. * Don't remove components if only updating the DB. * Don't remove components if files are not being deleted. */ if (nodelete) { echoDebug(DBG_PKGREMOVE_REM_NODEL, pkginst, zoneName ? zoneName : "global"); } else if (is_depend_pkginfo_DB()) { echoDebug(DBG_PKGREMOVE_REM_DBUPD, pkginst, zoneName ? zoneName : "global"); } else { echoDebug(DBG_PKGREMOVE_REM, pkginst, zoneName ? zoneName : "global"); /* * remove package one class at a time */ /* reverse order of classes */ for (i = cl_getn() - 1; i >= 0; i--) { rmclass(cl_nam(i), pkgrmremote, zoneName); } rmclass(NULL, pkgrmremote, zoneName); } z_destroyMountTable(); /* * Execute postremove script, if any * Don't execute postremove script if only updating the DB. * Don't execute postremove script if files are not being deleted. */ /* update the lock - at the postremove script */ lockupd("postremove"); /* execute postremove script if one is provided */ (void) snprintf(script, sizeof (script), "%s/postremove", pkgbin); if (access(script, F_OK) != 0) { /* no script present */ echoDebug(DBG_PKGREMOVE_PIC_NONE, pkginst, zoneName ? zoneName : "global"); } else if (nodelete) { /* not deleting files: skip postremove script */ echoDebug(DBG_PKGREMOVE_PIC_NODEL, pkginst, script, zoneName ? zoneName : "global"); } else if (is_depend_pkginfo_DB()) { /* updating db only: skip postremove script */ echoDebug(DBG_PKGREMOVE_PIC_DBUPD, pkginst, script, zoneName ? zoneName : "global"); } else { /* script present and ok to run: run the script */ set_ulimit("postremove", ERR_POSTREMOVE); if (zoneName == (char *)NULL) { echo(MSG_PKGREMOVE_EXEPIC_GZ); echoDebug(DBG_PKGREMOVE_EXEPIC_GZ, pkginst, script); } else { echo(MSG_PKGREMOVE_EXEPIC_LZ, zoneName); echoDebug(DBG_PKGREMOVE_EXEPIC_LZ, pkginst, script, zoneName); } putparam("PKG_PROC_SCRIPT", "postremove"); putparam("TMPDIR", tmpdir); if (pkgverbose) { ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER, PROC_GRP, SHELL, "-x", script, NULL), ERR_POSTREMOVE); } else { ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER, PROC_GRP, SHELL, script, NULL), ERR_POSTREMOVE); } clr_ulimit(); } if (zoneName == (char *)NULL) { echo(MSG_PKGREMOVE_UPDINF_GZ); } else { echo(MSG_PKGREMOVE_UPDINF_LZ, zoneName); } if (delmap(1, pkginst, &pkgserver, &tmpfp) != 0) { progerr(ERR_DB_QUERY, pkginst); quit(99); } if (!warnflag && !failflag) { (void) chdir("/"); if (rrmdir(pkgloc)) warnflag++; } if ((z_running_in_global_zone() == B_TRUE) && (pkgIsPkgInGzOnly(get_inst_root(), pkginst) == B_TRUE)) { boolean_t b; b = pkgRemovePackageFromGzonlyList(get_inst_root(), pkginst); if (b == B_FALSE) { progerr(ERR_PKGREMOVE_GZONLY_REMOVE, pkginst); ckreturn(1, NULL); } } /* release the generic package lock */ (void) unlockinst(); pkgcloseserver(pkgserver); quit(0); /* LINTED: no return */ }
static void rmclass(char *aclass, int rm_remote, char *a_zoneName) { struct cfent *ept; FILE *fp; char tmpfile[PATH_MAX]; char script[PATH_MAX]; int i; char *tmp_path; char *save_path = NULL; struct stat st; if (aclass == NULL) { for (i = 0; i < eptnum; i++) { if (eptlist[i] != NULL) { rmclass(eptlist[i]->pkg_class, rm_remote, a_zoneName); } } return; } /* locate class action script to execute */ (void) snprintf(script, sizeof (script), "%s/r.%s", pkgbin, aclass); if (access(script, F_OK) != 0) { (void) snprintf(script, sizeof (script), "%s/r.%s", PKGSCR, aclass); if (access(script, F_OK) != 0) script[0] = '\0'; } if (script[0] != '\0') { int td; (void) snprintf(tmpfile, sizeof (tmpfile), "%s/RMLISTXXXXXX", tmpdir); td = mkstemp(tmpfile); if (td == -1) { progerr(ERR_TMPFILE); quit(99); } if ((fp = fdopen(td, "w")) == NULL) { progerr(ERR_WTMPFILE, tmpfile); quit(99); } } if (a_zoneName == (char *)NULL) { echo(MSG_PKGREMOVE_REMPATHCLASS_GZ, aclass); } else { echo(MSG_PKGREMOVE_REMPATHCLASS_LZ, aclass, a_zoneName); } /* process paths in reverse order */ i = eptnum; while (--i >= 0) { ept = eptlist[i]; if ((ept == NULL) || strcmp(aclass, ept->pkg_class)) { continue; } /* save the path, and prepend the ir */ if (is_an_inst_root()) { save_path = ept->path; tmp_path = fixpath(ept->path); ept->path = tmp_path; } if (!ept->ftype || (ept->ftype == '^' && !script[0])) { /* * A path owned by more than one package is marked with * a NULL ftype (seems odd, but that's how it's * done). Such files are sacro sanct. Shared editable * files are a special case, and are marked with an * ftype of '^'. These files should only be ignored if * no class action script is present. It is the CAS's * responsibility to not remove the editable object. */ echo(MSG_SHARED, ept->path); } else if (ept->pinfo->status == SERVED_FILE && !rm_remote) { /* * If the path is provided to the client from a * server, don't remove anything unless explicitly * requested through the "-f" option. */ echo(MSG_SERVER, ept->path); } else if (script[0]) { /* * If there's a class action script, just put the * path name into the list. */ (void) fprintf(fp, "%s\n", ept->path); } else if (strchr("dx", ept->ftype) != NULL || (lstat(ept->path, &st) == 0 && S_ISDIR(st.st_mode))) { /* Directories are rmdir()'d. */ if (rmdir(ept->path)) { if (errno == EBUSY) { echo(MSG_DIRBUSY, ept->path); } else if (errno == EEXIST) { echo(MSG_NOTEMPTY, ept->path); } else if (errno != ENOENT) { progerr(ERR_RMDIR, ept->path); warnflag++; } } else { if (ept->pinfo->status == SERVED_FILE) { echo(MSG_RMSRVR, ept->path); } else { echo("%s", ept->path); } } } else { /* * Before removing this object one more * check should be done to assure that a * shared object is not removed. * This can happen if the original object * was incorrectly updated with the * incorrect class identifier. * This handles pathologcal cases that * weren't handled above. */ if (ept->npkgs > 1) { echo(MSG_SHARED, ept->path); continue; } /* Regular files are unlink()'d. */ if (unlink(ept->path)) { if (errno != ENOENT) { progerr(ERR_RMPATH, ept->path); warnflag++; } } else { if (ept->pinfo->status == SERVED_FILE) { echo(MSG_RMSRVR, ept->path); } else { echo("%s", ept->path); } } } /* restore the original path */ if (is_an_inst_root()) { ept->path = save_path; } /* * free memory allocated for this entry memory used for * pathnames will be freed later by a call to pathdup() */ if (eptlist[i]) { free(eptlist[i]); } eptlist[i] = NULL; } if (script[0]) { (void) fclose(fp); set_ulimit(script, ERR_CASFAIL); if (pkgverbose) ckreturn(pkgexecl(tmpfile, CAS_STDOUT, CAS_USER, CAS_GRP, SHELL, "-x", script, NULL), ERR_CASFAIL); else ckreturn(pkgexecl(tmpfile, CAS_STDOUT, CAS_USER, CAS_GRP, SHELL, script, NULL), ERR_CASFAIL); clr_ulimit(); if (isfile(NULL, tmpfile) == 0) { if (unlink(tmpfile) == -1) progerr(ERR_RMPATH, tmpfile); } } }
static char * check_db_entry(VFP_T *vfpo, struct cfextra *entry, int rmflag, char *myclass, int *dbchg) { struct pinfo *pinfo; int fs_entry; char *save_path = NULL; char *tp; /* write this entry to the contents file */ if (myclass && strcmp(myclass, entry->cf_ent.pkg_class)) { if (putcvfpfile(&entry->cf_ent, vfpo)) { progerr(gettext(ERR_WRITE)); quit(99); } return (NULL); } /* * Now scan each package instance holding this file or * directory and see if it matches the package we are * updating here. */ pinfo = entry->cf_ent.pinfo; while (pinfo) { if (strcmp(pkginst, pinfo->pkg) == 0) break; pinfo = pinfo->next; } /* * If pinfo == NULL at this point, then this file or * directory isn't part of the package of interest. * So the loop below executes only on files in the package * of interest. */ save_path = NULL; if (pinfo) { if (rmflag && (pinfo->status == RM_RDY)) { *dbchg = 1; (void) eptstat(&(entry->cf_ent), pkginst, '@'); if (entry->cf_ent.npkgs) { if (putcvfpfile(&(entry->cf_ent), vfpo)) { progerr(gettext(ERR_WRITE)); quit(99); } } return (NULL); } else if (!rmflag && (pinfo->status == INST_RDY)) { *dbchg = 1; /* tp is the server-relative path */ tp = fixpath(entry->cf_ent.path); /* save_path is the cmd line path */ save_path = entry->cf_ent.path; /* entry has the server-relative path */ entry->cf_ent.path = tp; /* * The next if statement figures out how * the contents file entry should be * annotated. * * Don't install or verify objects for * remote, read-only filesystems. We * need only verify their presence and * flag them appropriately from some * server. Otherwise, ok to do final * check. */ fs_entry = fsys(entry->cf_ent.path); if (is_remote_fs_n(fs_entry) && !is_fs_writeable_n(fs_entry)) { /* * Mark it shared whether it's present * or not. life's too funny for me * to explain. */ pinfo->status = SERVED_FILE; /* * restore for now. This may * chg soon. */ entry->cf_ent.path = save_path; } else { /* * If the object is accessible, check * the new entry for existence and * attributes. If there's a problem, * mark it NOT_FND; otherwise, * ENTRY_OK. */ if (is_mounted_n(fs_entry)) { int n; n = finalck((&entry->cf_ent), 1, 1, B_FALSE); pinfo->status = ENTRY_OK; if (n != 0) { pinfo->status = NOT_FND; } } /* * It's not remote, read-only but it * may look that way to the client. * If it does, overwrite the above * result - mark it shared. */ if (is_served_n(fs_entry)) pinfo->status = SERVED_FILE; /* restore original path */ entry->cf_ent.path = save_path; /* and clear save_path */ save_path = NULL; } } } /* Output entry to contents file. */ if (putcvfpfile(&(entry->cf_ent), vfpo)) { progerr(gettext(ERR_WRITE)); quit(99); } return (save_path); }
/* * For the pine composer, we don't want to take over the whole screen * for editing. the first some odd lines are to be used for message * header information editing. */ void edinit(char bname[]) { register BUFFER *bp; register WINDOW *wp; if(Pmaster) func_init(); bp = bfind(bname, TRUE, BFWRAPOPEN); /* First buffer */ wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */ if (bp==NULL || wp==NULL){ if(Pmaster) return; else exit(1); } curbp = bp; /* Make this current */ wheadp = wp; curwp = wp; wp->w_wndp = NULL; /* Initialize window */ wp->w_bufp = bp; bp->b_nwnd = 1; /* Displayed. */ wp->w_linep = bp->b_linep; wp->w_dotp = bp->b_linep; wp->w_doto = 0; wp->w_markp = wp->w_imarkp = NULL; wp->w_marko = wp->w_imarko = 0; bp->b_linecnt = -1; if(Pmaster){ term.t_mrow = Pmaster->menu_rows; wp->w_toprow = ComposerTopLine = COMPOSER_TOP_LINE; wp->w_ntrows = term.t_nrow - COMPOSER_TOP_LINE - term.t_mrow; fillcol = Pmaster->fillcolumn; strncpy(opertree, (Pmaster->oper_dir && strlen(Pmaster->oper_dir) < NLINE) ? Pmaster->oper_dir : "", sizeof(opertree)); opertree[sizeof(opertree)-1] = '\0'; input_cs = Pmaster->input_cs; } else{ if(sup_keyhelp) term.t_mrow = 0; else term.t_mrow = 2; wp->w_toprow = 2; wp->w_ntrows = term.t_nrow - 2 - term.t_mrow; if(userfillcol > 0) /* set fill column */ fillcol = userfillcol; else fillcol = term.t_ncol - 6; } /* * MDSCUR mode implies MDTREE mode with a opertree of home directory, * unless opertree has been set differently. */ if((gmode & MDSCUR) && !opertree[0]){ strncpy(opertree, gethomedir(NULL), sizeof(opertree)); opertree[sizeof(opertree)-1] = '\0'; } if(*opertree) fixpath(opertree, sizeof(opertree)); wp->w_force = 0; wp->w_flag = WFMODE|WFHARD; /* Full. */ }
} int stream_unlink(const char *path) { int rc; drop_privilege(); rc = (unlink(fixpath(path))) ? -errno : 0; regain_privilege(); return rc; } int stream_rename(const char *old, const char *new) { int rc; drop_privilege(); rc = (rename(fixpath(old), fixpath(new))) ? -errno : 0; regain_privilege(); return rc; } int stream_chmod(const char *path, mode_t mode) { int rc; drop_privilege(); rc = (chmod(fixpath(path), mode)) ? -errno : 0; regain_privilege(); return rc; } int stream_chown(const char *path, uid_t uid, gid_t gid) {