Beispiel #1
0
/* 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);
}
Beispiel #2
0
/* 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;
}
Beispiel #3
0
/* 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;
}
Beispiel #4
0
/* 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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
/*
 * 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);
}
Beispiel #7
0
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*/
}
Beispiel #8
0
/* 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);
}