/* The user has just finished mounting/unmounting this path. * Update the list of user-mounted filesystems. */ void mount_user_mount(const char *path) { if (mount_is_mounted(path, NULL, NULL)) g_hash_table_insert(user_mounts, pathdup(path), "yes"); else g_hash_table_remove(user_mounts, path); }
/* Convert uri to path and call run_by_path() */ gboolean run_by_uri(const gchar *uri, gchar **errmsg) { gboolean retval; gchar *tmp, *tmp2; gchar *scheme; gchar *cmd; scheme=get_uri_scheme((EscapedPath *) uri); if(!scheme) { *errmsg=g_strdup_printf(_("'%s' is not a valid URI"), uri); return FALSE; } if(strcmp(scheme, "file")==0) { tmp=get_local_path((EscapedPath *) uri); if(tmp) { tmp2=pathdup(tmp); retval=run_by_path(tmp2); if(!retval) *errmsg=g_strdup_printf(_("%s not accessable"), tmp); g_free(tmp2); g_free(tmp); } else { retval=FALSE; *errmsg=g_strdup_printf(_("Non-local URL %s"), uri); } } else if((cmd=choices_find_xdg_path_load(scheme, "URI", SITE))) { DirItem *item; item=diritem_new(scheme); diritem_restat(cmd, item, NULL); run_with_args(cmd, item, uri); retval=TRUE; /* we hope... */ diritem_free(item); g_free(cmd); } else { retval=FALSE; *errmsg=g_strdup_printf(_("%s: no handler for %s"), uri, scheme); } g_free(scheme); return retval; }
/* Check if we have an up-to-date thumbnail for this image. * If so, return it. Otherwise, returns NULL. */ static GdkPixbuf* get_thumbnail_for(const char *pathname) { GdkPixbuf *thumb = NULL; char *thumb_path, *uri; const char *ssize, *smtime; struct stat info; time_t ttime, now; char* path = pathdup(pathname); uri = g_filename_to_uri(path, NULL, NULL); if(!uri) uri = g_strconcat("file://", path, NULL); char* md5 = md5_hash(uri); g_free(uri); thumb_path = g_strdup_printf("%s/.thumbnails/normal/%s.png", g_get_home_dir(), md5); g_free(md5); thumb = gdk_pixbuf_new_from_file(thumb_path, NULL); if (!thumb) goto err; // Note that these don't need freeing... ssize = gdk_pixbuf_get_option(thumb, "tEXt::Thumb::Size"); if (!ssize) goto err; smtime = gdk_pixbuf_get_option(thumb, "tEXt::Thumb::MTime"); if (!smtime) goto err; if (stat(path, &info) != 0) goto err; ttime=(time_t) atol(smtime); time(&now); if (info.st_mtime != ttime && now>ttime+PIXMAP_THUMB_TOO_OLD_TIME) goto err; if (info.st_size < atol(ssize)) goto err; goto out; err: if (thumb) gdk_pixbuf_unref(thumb); thumb = NULL; out: g_free(path); g_free(thumb_path); return thumb; }
/* TRUE if this mount point was mounted by the user, and still is */ gboolean mount_is_user_mounted(const gchar *path) { gboolean retval; gchar *real; real = pathdup(path); retval = g_hash_table_lookup(user_mounts, path) != NULL; if (retval) { /* Check the status is up-to-date */ mount_user_mount(real); retval = g_hash_table_lookup(user_mounts, path) != NULL; } g_free(real); return retval; }
static void extract_stdout(struct archive *a, struct archive_entry *e) { char *pathname; mode_t filetype; int cr, text, warn; ssize_t len; unsigned char *p, *q, *end; pathname = pathdup(archive_entry_pathname(e)); filetype = archive_entry_filetype(e); /* I don't think this can happen in a zipfile.. */ if (!S_ISDIR(filetype) && !S_ISREG(filetype)) { warningx("skipping non-regular entry '%s'", pathname); ac(archive_read_data_skip(a)); free(pathname); return; } /* skip directories in -j case */ if (S_ISDIR(filetype)) { ac(archive_read_data_skip(a)); free(pathname); return; } /* apply include / exclude patterns */ if (!accept_pathname(pathname)) { ac(archive_read_data_skip(a)); free(pathname); return; } if (c_opt) info("x %s\n", pathname); text = a_opt; warn = 0; cr = 0; for (int n = 0; ; n++) { len = archive_read_data(a, buffer, sizeof buffer); if (len < 0) ac(len); /* left over CR from previous buffer */ if (a_opt && cr) { if (len == 0 || buffer[0] != '\n') { if (fwrite("\r", 1, 1, stderr) != 1) error("write('%s')", pathname); } cr = 0; } /* EOF */ if (len == 0) break; end = buffer + len; /* * Detect whether this is a text file. The correct way to * do this is to check the least significant bit of the * "internal file attributes" field of the corresponding * file header in the central directory, but libarchive * does not read the central directory, so we have to * guess by looking for non-ASCII characters in the * buffer. Hopefully we won't guess wrong. If we do * guess wrong, we print a warning message later. */ if (a_opt && n == 0) { for (p = buffer; p < end; ++p) { if (!isascii((unsigned char)*p)) { text = 0; break; } } } /* simple case */ if (!a_opt || !text) { if (fwrite(buffer, 1, len, stdout) != (size_t)len) error("write('%s')", pathname); continue; } /* hard case: convert \r\n to \n (sigh...) */ for (p = buffer; p < end; p = q + 1) { for (q = p; q < end; q++) { if (!warn && !isascii(*q)) { warningx("%s may be corrupted due" " to weak text file detection" " heuristic", pathname); warn = 1; } if (q[0] != '\r') continue; if (&q[1] == end) { cr = 1; break; } if (q[1] == '\n') break; } if (fwrite(p, 1, q - p, stdout) != (size_t)(q - p)) error("write('%s')", pathname); } } free(pathname); }
/* * Extract a zipfile entry: first perform some sanity checks to ensure * that it is either a directory or a regular file and that the path is * not absolute and does not try to break out of the current directory; * then call either extract_dir() or extract_file() as appropriate. * * This is complicated a bit by the various ways in which we need to * manipulate the path name. Case conversion (if requested by the -L * option) happens first, but the include / exclude patterns are applied * to the full converted path name, before the directory part of the path * is removed in accordance with the -j option. Sanity checks are * intentionally done earlier than they need to be, so the user will get a * warning about insecure paths even for files or directories which * wouldn't be extracted anyway. */ static void extract(struct archive *a, struct archive_entry *e) { char *pathname, *realpathname; mode_t filetype; char *p, *q; pathname = pathdup(archive_entry_pathname(e)); filetype = archive_entry_filetype(e); /* sanity checks */ if (pathname[0] == '/' || strncmp(pathname, "../", 3) == 0 || strstr(pathname, "/../") != NULL) { warningx("skipping insecure entry '%s'", pathname); ac(archive_read_data_skip(a)); free(pathname); return; } /* I don't think this can happen in a zipfile.. */ if (!S_ISDIR(filetype) && !S_ISREG(filetype)) { warningx("skipping non-regular entry '%s'", pathname); ac(archive_read_data_skip(a)); free(pathname); return; } /* skip directories in -j case */ if (S_ISDIR(filetype) && j_opt) { ac(archive_read_data_skip(a)); free(pathname); return; } /* apply include / exclude patterns */ if (!accept_pathname(pathname)) { ac(archive_read_data_skip(a)); free(pathname); return; } /* apply -j and -d */ if (j_opt) { for (p = q = pathname; *p; ++p) if (*p == '/') q = p + 1; realpathname = pathcat(d_arg, q); } else { realpathname = pathcat(d_arg, pathname); } /* ensure that parent directory exists */ make_parent(realpathname); if (S_ISDIR(filetype)) extract_dir(a, e, realpathname); else extract_file(a, e, &realpathname); free(realpathname); free(pathname); }
void quit(int retcode) { /* disable interrupts */ (void) signal(SIGINT, SIG_IGN); (void) signal(SIGHUP, SIG_IGN); /* process return code if not quit(99) */ if (retcode != 99) { if ((retcode % 10) == 0) { if (failflag) { retcode += 1; } else if (warnflag) { retcode += 2; } } if (ireboot) { retcode = (retcode % 10) + 20; } if (dreboot) { retcode = (retcode % 10) + 10; } } /* if set remove dstream temporary directory */ if (dstreamTempDir != (char *)NULL) { echoDebug(DBG_REMOVING_DSTREAM_TMPDIR, dstreamTempDir); (void) rrmdir(dstreamTempDir); dstreamTempDir = (char *)NULL; } /* If we're in dryrun mode, write out the dryrun file(s). */ if (in_dryrun_mode()) { char exit_msg[200]; set_dr_info(EXITCODE, retcode); if (failflag || warnflag) { set_dr_exitmsg(msgtext); } else { /* LINTED variable format specified */ (void) snprintf(exit_msg, sizeof (exit_msg), qreason(1, retcode, installStarted, includeZonename), (pkginst ? pkginst : "unknown"), zoneName); set_dr_exitmsg(exit_msg); } write_dryrun_file(extlist); ptext(stderr, MSG_DRYRUN_DONE); ptext(stderr, MSG_NOCHANGE); if (tmpdir[0] != NULL) (void) rrmdir(tmpdir); } else { /* fix bug #1082589 that deletes root file */ if (tmpdir[0] != NULL) { (void) rrmdir(tmpdir); } /* send mail to appropriate user list */ mailmsg(retcode); /* display message about this installation */ quitmsg(retcode); } /* * In the event that this quit() was called prior to completion of * the task, do an unlockinst() just in case. */ unlockinst(); /* Unmount anything that's our responsibility. */ (void) unmount_client(); /* * No need to umount device since calling process * was responsible for original mount */ if (!updatingExistingPackage) { if (!installStarted && pkgloc[0]) { /* * install not yet started; if package install * location is defined, remove the package. */ echoDebug(DBG_QUIT_REMOVING_PKGDIR, pkgloc); (void) chdir("/"); if (pkgloc[0]) { (void) rrmdir(pkgloc); } } } else { if (!installStarted) { /* * If we haven't started, but have already done * the <PKGINST>/install directory rename, then * remove the new <PKGINST>/install directory * and rename <PKGINST>/install.save back to * <PKGINST>/install. */ if (pkgloc_sav[0] && !access(pkgloc_sav, F_OK)) { if (pkgloc[0] && !access(pkgloc, F_OK)) (void) rrmdir(pkgloc); if (rename(pkgloc_sav, pkgloc) == -1) { progerr(ERR_PACKAGEBINREN, pkgloc_sav, pkgloc); } } } else { if (pkgloc_sav[0] && !access(pkgloc_sav, F_OK)) { echoDebug(DBG_QUIT_REMOVING_PKGSAV, pkgloc_sav); (void) rrmdir(pkgloc_sav); } } } /* * pkginst can be null if an administration setting doesn't all * the package to be installed. Make sure pkginst exeists before * updating the DB */ if (dparts > 0) ds_skiptoend(pkgdev.cdevice); (void) ds_close(1); /* Free the filesystem table. */ fs_tab_free(); /* Free the package information lists. */ pinfo_free(); /* Free all stragglers. */ bl_free(BL_ALL); (void) pathdup(NULL); /* Free regfiles. */ regfiles_free(); /* final exit debugging message */ echoDebug(DBG_EXIT_WITH_CODE, retcode); exit(retcode); /*NOTREACHED*/ }
/* Bring this item's structure uptodate. * 'parent' is optional; it saves one stat() for directories. */ void diritem_restat(const guchar *path, DirItem *item, struct stat *parent) { struct stat info; if (item->_image) { g_object_unref(item->_image); item->_image = NULL; } item->flags = 0; item->mime_type = NULL; if (mc_lstat(path, &info) == -1) { item->lstat_errno = errno; item->base_type = TYPE_ERROR; item->size = 0; item->mode = 0; item->mtime = item->ctime = item->atime = 0; item->uid = (uid_t) -1; item->gid = (gid_t) -1; } else { guchar *target_path; item->lstat_errno = 0; item->size = info.st_size; item->mode = info.st_mode; item->atime = info.st_atime; item->ctime = info.st_ctime; item->mtime = info.st_mtime; item->uid = info.st_uid; item->gid = info.st_gid; if (ABOUT_NOW(item->mtime) || ABOUT_NOW(item->ctime)) item->flags |= ITEM_FLAG_RECENT; if (xattr_have(path)) item->flags |= ITEM_FLAG_HAS_XATTR; item->label = xlabel_get(path); if (S_ISLNK(info.st_mode)) { if (mc_stat(path, &info)) item->base_type = TYPE_ERROR; else item->base_type = mode_to_base_type(info.st_mode); item->flags |= ITEM_FLAG_SYMLINK; target_path = pathdup(path); } else { item->base_type = mode_to_base_type(info.st_mode); target_path = (guchar *) path; } if (item->base_type == TYPE_DIRECTORY) { if (mount_is_mounted(target_path, &info, target_path == path ? parent : NULL)) item->flags |= ITEM_FLAG_MOUNT_POINT | ITEM_FLAG_MOUNTED; else if (g_hash_table_lookup(fstab_mounts, target_path)) item->flags |= ITEM_FLAG_MOUNT_POINT; } if (path != target_path) g_free(target_path); } if (item->base_type == TYPE_DIRECTORY) { /* KRJW: info.st_uid will be the uid of the dir, regardless * of whether `path' is a dir or a symlink to one. Note that * if path is a symlink to a dir, item->uid will be the uid * of the *symlink*, but we really want the uid of the dir * to which the symlink points. */ examine_dir(path, item, &info); } else if (item->base_type == TYPE_FILE) { if (item->flags & ITEM_FLAG_SYMLINK) { guchar *link_path; link_path = pathdup(path); item->mime_type = type_from_path(link_path ? link_path : path); g_free(link_path); } else item->mime_type = type_from_path(path); /* Note: for symlinks we need the mode of the target */ if (info.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { /* Note that the flag is set for ALL executable * files, but the mime_type must also be executable * for clicking on the file to run it. */ item->flags |= ITEM_FLAG_EXEC_FILE; if (item->mime_type == NULL || item->mime_type == application_octet_stream) { item->mime_type = application_executable; } else if (item->mime_type == text_plain && !strchr(item->leafname, '.')) { item->mime_type = application_x_shellscript; } } else if (item->mime_type == application_x_desktop) { item->flags |= ITEM_FLAG_EXEC_FILE; } if (!item->mime_type) item->mime_type = text_plain; check_globicon(path, item); if (item->mime_type == application_x_desktop && item->_image == NULL) { item->_image = g_fscache_lookup(desktop_icon_cache, path); } } else check_globicon(path, item); if (!item->mime_type) item->mime_type = mime_type_from_base_type(item->base_type); }