Exemplo n.º 1
0
int uninstall_grub2(lickdir_t *lick) {
    char drive = mount_uefi_partition();
    if(drive == '\0') {
        if(!lick->err)
            lick->err = strdup2("Could not mount EFI partition.");
        return 0;
    }

    if(!fix_grub2_inner(lick, GRUB2_FIX_UNINSTALL, drive)) {
        unmount_uefi_partition(drive);
        if(!lick->err)
            lick->err = strdup2("Could not revert boot fix.");
        return 0;
    }

    char *grub_cfg = unix_path(concat_strs(2, lick->drive, "/lickgrub.cfg"));
    if(!has_valuable_info(grub_cfg)) {
        unlink_file(grub_cfg);
    }
    free(grub_cfg);

    char *lick_cert = strdup2("?:/lick.cer");
    lick_cert[0] = drive;
    unlink_file(lick_cert);
    free(lick_cert);

    char lick_dir[] = "?:/EFI/LICK";
    lick_dir[0] = drive;
    unlink_recursive(lick_dir);
    unmount_uefi_partition(drive);

    return 1;
}
Exemplo n.º 2
0
static void cache_file_remove(const gchar *path)
{
	if (path && isfile(path) && !unlink_file(path))
		{
		DEBUG_1("Failed to remove cache file %s", path);
		}
}
Exemplo n.º 3
0
static gint thumb_loader_std_next_source(ThumbLoaderStd *tl, gint remove_broken)
{
	image_loader_free(tl->il);
	tl->il = NULL;

	if (tl->thumb_path)
		{
		if (!tl->thumb_path_local && remove_broken)
			{
			if (debug) printf("thumb broken, unlinking: %s\n", tl->thumb_path);
			unlink_file(tl->thumb_path);
			}

		g_free(tl->thumb_path);
		tl->thumb_path = NULL;

		if (!tl->thumb_path_local)
			{
			tl->thumb_path = thumb_loader_std_cache_path(tl, TRUE, NULL, FALSE);
			if (isfile(tl->thumb_path) && thumb_loader_std_setup(tl, tl->thumb_path))
				{
				tl->thumb_path_local = TRUE;
				return TRUE;
				}

			g_free(tl->thumb_path);
			tl->thumb_path = NULL;
			}

		if (thumb_loader_std_setup(tl, tl->source_path)) return TRUE;
		}

	thumb_loader_std_save(tl, NULL);
	return FALSE;
}
void runUnlinkTests(){
	unlink_file();
	unlink_enoent();
	unlink_enotdir();
	unlink_recreate();
	unlink_rdonlyfs();
}
Exemplo n.º 5
0
static gint cache_manager_standard_clean_clear_cb(gpointer data)
{
	CleanData *cd = data;

	if (cd->list)
		{
		FileData *next_fd;

		next_fd = cd->list->data;
		cd->list = g_list_remove(cd->list, next_fd);

		DEBUG_1("thumb removed: %s", next_fd->path);

		unlink_file(next_fd->path);
		file_data_unref(next_fd);

		cd->count_done++;
		if (cd->count_total != 0)
			{
			gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(cd->progress),
						      (gdouble)cd->count_done / cd->count_total);
			}

		return TRUE;
		}

	cd->idle_id = 0;
	cache_manager_standard_clean_done(cd);
	return FALSE;
}
Exemplo n.º 6
0
Arquivo: nt.c Projeto: noryb009/lick
int uninstall_loader_nt(sys_info_t *info, lickdir_t *lick) {
    (void)info;

    // remove from boot.ini
    char *boot_drive = boot_drive_nt();
    if(!boot_drive) {
        if(!lick->err)
            lick->err = concat_strs(2, "Could not load boot loader file: ", BOOT_FILE);
        return 0;
    }
    char *boot_ini = boot_ini_path_with_drive(boot_drive);

    int ret = apply_fn_to_file(boot_ini, uninstall_from_boot_ini, 0, lick);
    free(boot_ini);
    if(!ret) {
        free(boot_drive);
        return 0;
    }

    char *pupldr = concat_strs(2, boot_drive, "/pupldr");
    unlink_file(pupldr);

    free(pupldr);
    free(boot_drive);
    return 1;
}
Exemplo n.º 7
0
/*===========================================================================*
 *				fs_unlink				     *
 *===========================================================================*/
int fs_unlink()
{
/* Perform the unlink(name) or rmdir(name) system call. The code for these two
 * is almost the same.  They differ only in some condition testing.  Unlink()
 * may be used by the superuser to do dangerous things; rmdir() may not.
 */
  register struct inode *rip;
  struct inode *rldirp;
  int r;
  char string[NAME_MAX + 1];
  phys_bytes len;

  /* Copy the last component */
  len = fs_m_in.REQ_PATH_LEN; /* including trailing '\0' */
  if (len > NAME_MAX + 1 || len > EXT2_NAME_MAX + 1)
	return(ENAMETOOLONG);

  r = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT,
                       (vir_bytes) 0, (vir_bytes) string, (size_t) len);
  if (r != OK) return r;
  NUL(string, len, sizeof(string));

  /* Temporarily open the dir. */
  if( (rldirp = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
	  return(EINVAL);

  /* The last directory exists.  Does the file also exist? */
  rip = advance(rldirp, string, IGN_PERM);
  r = err_code;

  /* If error, return inode. */
  if(r != OK) {
	/* Mount point? */
	if (r == EENTERMOUNT || r == ELEAVEMOUNT) {
		put_inode(rip);
		r = EBUSY;
	}
	put_inode(rldirp);
	return(r);
  }

  /* Now test if the call is allowed, separately for unlink() and rmdir(). */
  if(fs_m_in.m_type == REQ_UNLINK) {
	  /* Only the su may unlink directories, but the su can unlink any
	   * dir.*/
	  if( (rip->i_mode & I_TYPE) == I_DIRECTORY) r = EPERM;

	  /* Actually try to unlink the file; fails if parent is mode 0 etc. */
	  if (r == OK) r = unlink_file(rldirp, rip, string);
  } else {
	  r = remove_dir(rldirp, rip, string); /* call is RMDIR */
  }

  /* If unlink was possible, it has been done, otherwise it has not. */
  put_inode(rip);
  put_inode(rldirp);
  return(r);
}
Exemplo n.º 8
0
static void cache_file_move(const gchar *src, const gchar *dest)
{
	if (!dest || !src || !isfile(src)) return;

	if (!move_file(src, dest))
		{
		DEBUG_1("Failed to move cache file \"%s\" to \"%s\"", src, dest);
		/* we remove it anyway - it's stale */
		unlink_file(src);
		}
}
Exemplo n.º 9
0
static void thumb_std_maint_move_validate_cb(const gchar *path, gint valid, gpointer data)
{
	TMaintMove *tm = data;
	GdkPixbuf *pixbuf;

	pixbuf = thumb_loader_std_get_pixbuf(tm->tl, FALSE);
	if (pixbuf)
		{
		const gchar *uri;
		const gchar *mtime_str;

		uri = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_URI);
		mtime_str = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_MTIME);

		if (uri && mtime_str && strcmp(uri, tm->source_uri) == 0)
			{
			gchar *pathl;

			/* The validation utility abuses ThumbLoader, and we
			 * abuse the utility just to load the thumbnail,
			 * but the loader needs to look sane for the save to complete.
			 */

			tm->tl->cache_enable = TRUE;
			tm->tl->cache_hit = FALSE;
			tm->tl->cache_local = FALSE;

			g_free(tm->tl->source_path);
			tm->tl->source_path = g_strdup(tm->dest);
			tm->tl->source_mtime = strtol(mtime_str, NULL, 10);

			pathl = path_from_utf8(tm->tl->source_path);
			g_free(tm->tl->thumb_uri);
			tm->tl->thumb_uri = g_filename_to_uri(pathl, NULL, NULL);
			tm->tl->local_uri = filename_from_path(tm->tl->thumb_uri);
			g_free(pathl);

			g_free(tm->tl->thumb_path);
			tm->tl->thumb_path = NULL;
			tm->tl->thumb_path_local = FALSE;

			if (debug) printf("thumb move attempting save:\n");

			thumb_loader_std_save(tm->tl, pixbuf);
			}

		if (debug) printf("thumb move unlink: %s\n", tm->thumb_path);
		unlink_file(tm->thumb_path);
		}

	thumb_std_maint_move_step(tm);
}
Exemplo n.º 10
0
int
main(int argc, char **argv)
{
    int optind = 0;
    int i;
    struct fhb_handle *handles;


    if (agetarg(args, argc, argv, &optind, AARG_GNUSTYLE))
	usage(1);

    if (help_flag)
	usage(0);

    if (num_files <= 0)
	usage(1);

    if (write_file < 0)
	usage(1);

#ifdef KERBEROS
    if (!k_hasafs())
#endif
	errx(1, "no afs kernel module");

    handles = emalloc(num_files * sizeof(*handles));

    starttesting("creating files");
    for (i = 0; i < num_files; i++)
	create_file(i, &handles[i]);
    endtesting();

    for (i = 0; i < num_runs; i++)
	open_bench(i, handles);

    printf("==================\n");
    starttesting("unlink files");
    for (i = 0; i < num_files; i++)
	unlink_file(i);
    endtesting();

    printf("==================\n");
    starttesting("nop call");
    for (i = 0; i < num_files; i++)
	nop_call();
    endtesting();

    return 0;
}
Exemplo n.º 11
0
static void thumb_std_maint_remove_one(const gchar *source, const gchar *uri, gint local,
				       const gchar *subfolder)
{
	gchar *thumb_path;

	thumb_path = thumb_std_cache_path(source,
					  (local) ? filename_from_path(uri) : uri,
					  local, subfolder);
	if (isfile(thumb_path))
		{
		if (debug) printf("thumb removing: %s\n", thumb_path);
		unlink_file(thumb_path);
		}
	g_free(thumb_path);
}
Exemplo n.º 12
0
static gint thumb_loader_std_fail_check(ThumbLoaderStd *tl)
{
	gchar *fail_path;
	gint result = FALSE;

	fail_path = thumb_loader_std_cache_path(tl, FALSE, NULL, TRUE);
	if (isfile(fail_path))
		{
		GdkPixbuf *pixbuf;

		if (tl->cache_retry)
			{
			pixbuf = NULL;
			}
		else
			{
			gchar *pathl;

			pathl = path_from_utf8(fail_path);
			pixbuf = gdk_pixbuf_new_from_file(pathl, NULL);
			g_free(pathl);
			}

		if (pixbuf)
			{
			const gchar *mtime_str;

			mtime_str = gdk_pixbuf_get_option(pixbuf, THUMB_MARKER_MTIME);
			if (mtime_str && strtol(mtime_str, NULL, 10) == tl->source_mtime)
				{
				result = TRUE;
				if (debug)
					{
					printf("thumb fail valid: %s\n", tl->source_path);
					printf("           thumb: %s\n", fail_path);
					}
				}

			g_object_unref(G_OBJECT(pixbuf));
			}

		if (!result) unlink_file(fail_path);
		}
	g_free(fail_path);

	return result;
}
Exemplo n.º 13
0
/*===========================================================================*
 *				fs_unlink				     *
 *===========================================================================*/
int fs_unlink(ino_t dir_nr, char *name, int call)
{
    /* Perform the unlink(name) or rmdir(name) system call. The code for these two
     * is almost the same.  They differ only in some condition testing.
     */
    register struct inode *rip;
    struct inode *rldirp;
    int r;

    /* Temporarily open the dir. */
    if((rldirp = get_inode(fs_dev, dir_nr)) == NULL)
        return(EINVAL);

    /* The last directory exists.  Does the file also exist? */
    rip = advance(rldirp, name);
    r = err_code;

    /* If error, return inode. */
    if(r != OK) {
        put_inode(rldirp);
        return(r);
    }
    if (rip->i_mountpoint) {
        put_inode(rip);
        put_inode(rldirp);
        return(EBUSY);
    }

    /* Now test if the call is allowed, separately for unlink() and rmdir(). */
    if (call == FSC_UNLINK) {
        if( (rip->i_mode & I_TYPE) == I_DIRECTORY) r = EPERM;

        /* Actually try to unlink the file; fails if parent is mode 0 etc. */
        if (r == OK) r = unlink_file(rldirp, rip, name);
    } else {
        r = remove_dir(rldirp, rip, name); /* call is RMDIR */
    }

    /* If unlink was possible, it has been done, otherwise it has not. */
    put_inode(rip);
    put_inode(rldirp);
    return(r);
}
Exemplo n.º 14
0
static void editor_list_window_delete_dlg_ok_cb(GenericDialog *gd, gpointer data)
{
	EditorWindowDel_Data *ewdl = data;

	if (!unlink_file(ewdl->path))
		{
		gchar *text = g_strdup_printf(_("Unable to delete file:\n%s"), ewdl->path);
		warning_dialog(_("File deletion failed"), text, GTK_STOCK_DIALOG_WARNING, NULL);
		g_free(text);
		}
	else
		{
		/* refresh list */
		layout_editors_reload_start();
		/* idle function is not needed, everything should be cached */
		layout_editors_reload_finish(); 
		}

	editor_list_window_delete_dlg_cancel(gd, data);
}
Exemplo n.º 15
0
/*
	expire oldest message
*/
void expire_msg(Room *r, User *usr) {
char filename[MAX_PATHLEN];

	if (r == NULL)
		return;

	if (r->number == MAIL_ROOM) {
		if (usr == NULL)
			filename[0] = 0;
		else
			bufprintf(filename, sizeof(filename), "%s/%c/%s/%ld", PARAM_USERDIR, usr->name[0], usr->name, r->tail_msg);
	} else
		bufprintf(filename, sizeof(filename), "%s/%u/%ld", PARAM_ROOMDIR, r->number, r->tail_msg);

	if (r->head_msg - r->tail_msg > r->max_msgs) {
		if (filename[0] && unlink_file(filename) == -1)
			log_err("expire_msg(): failed to delete file %s", filename);

		r->tail_msg++;
		r->flags |= ROOM_DIRTY;
	}
}
Exemplo n.º 16
0
static void cache_manager_standard_clean_valid_cb(const gchar *path, gboolean valid, gpointer data)
{
	CleanData *cd = data;

	if (path)
		{
		if (!valid)
			{
			DEBUG_1("thumb cleaned: %s", path);
			unlink_file(path);
			}

		cd->count_done++;
		if (cd->count_total != 0)
			{
			gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(cd->progress),
						      (gdouble)cd->count_done / cd->count_total);
			}
		}

	cd->tl = NULL;
	if (cd->list)
		{
		FileData *next_fd;

		next_fd = cd->list->data;
		cd->list = g_list_remove(cd->list, next_fd);

		cd->tl = thumb_loader_std_thumb_file_validate(next_fd->path, cd->days,
							      cache_manager_standard_clean_valid_cb, cd);
		file_data_unref(next_fd);
		}
	else
		{
		cache_manager_standard_clean_done(cd);
		}
}
Exemplo n.º 17
0
Arquivo: config.c Projeto: XQF/xqf
static void dump_file (struct config_file *file) {
	GList *sptr, *kptr;
	struct config_section *section;
	struct config_key *key;
	FILE *f;
	char *fn;

	if (!file->dirty)
		return;

	if (file->read_only)
		return;

	if (!file->sections) {
		unlink_file (file->filename);
		return;
	}

	fn = file_in_dir (directories->data, file->filename);
	f = fopen (fn, "w");
	g_free (fn);

	if (f) {
		for (sptr = file->sections; sptr; sptr = sptr->next) {
			section = (struct config_section *) sptr->data;
			fprintf (f, "[%s]\n", section->name);

			for (kptr = section->keys; kptr; kptr = kptr->next) {
				key = (struct config_key *) kptr->data;
				fprintf (f, "%s=%s\n", key->name, key->value);
			}

			fprintf (f, "\n");
		}
		fclose (f);
	}
}
Exemplo n.º 18
0
static gint collection_save_private(CollectionData *cd, const gchar *path)
{
	FILE *f;
	GList *work;
	gchar *tmp_path;
	gchar *pathl;
	mode_t save_mask;

	if (!path && !cd->path) return FALSE;

	if (!path)
		{
		path = cd->path;
		}

	tmp_path = unique_filename(path, ".tmp", "_", 3);
	if (!tmp_path) return FALSE;

	pathl = path_from_utf8(tmp_path);
	save_mask = umask(0077);
	f = fopen(pathl, "w");
	umask(save_mask);
	g_free(pathl);

	if (!f)
		{
		/* file open failed */
		printf("failed to open collection (write) \"%s\"\n", tmp_path);
		g_free(tmp_path);
		return FALSE;
		}

	fprintf(f, "%s collection\n", GQVIEW_COLLECTION_MARKER);
	fprintf(f, "#created with GQview version %s\n", VERSION);

	collection_update_geometry(cd);
	if (cd->window_read)
		{
		fprintf(f, "#geometry: %d %d %d %d\n", cd->window_x, cd->window_y, cd->window_w, cd->window_h);
		}

	work = cd->list;
	while (work)
		{
		CollectInfo *ci = work->data;
		if (fprintf(f, "\"%s\"\n", ci->path) < 0)
			{
			fclose(f);
			printf("Error writing to %s\n", tmp_path);
			unlink_file(tmp_path);
			g_free(tmp_path);
			return FALSE;
			}
		work = work->next;
		}

	fprintf(f, "#end\n");

	fclose(f);

	copy_file_attributes(path, tmp_path, TRUE, FALSE);
	if (!rename_file(tmp_path, path))
		{
		printf("collection save unable to rename %s to %s\n", tmp_path, path);
		unlink_file(tmp_path);
		g_free(tmp_path);
		return FALSE;
		}

	g_free(tmp_path);

	if (!cd->path || strcmp(path, cd->path) != 0)
		{
		gchar *buf = cd->path;
		cd->path = g_strdup(path);
		path = cd->path;
		g_free(buf);

		g_free(cd->name);
		cd->name = g_strdup(filename_from_path(cd->path));

		collection_path_changed(cd);
		}

	cd->changed = FALSE;

	return TRUE;
}
Exemplo n.º 19
0
/* Copies "from" to "to".  Note that the functionality here is similar
   to the win32 function CopyFile, but (1) we copy LastAccessTime and
   CopyFile doesn't, (2) we set file attributes to the default set by
   the C library and CopyFile copies them.  Neither #1 nor #2 was intentional
   as far as I know, but changing them could be confusing, unless there
   is some reason they should be changed (this would need more
   investigation).  */
int copy_file (const char *from, const char *to, int force_overwrite, int must_exist)
{
    struct stat sb;
    struct utimbuf t;
    int fdin, fdout;
#ifdef UTIME_EXPECTS_WRITABLE
    int change_it_back = 0;
#endif

	TRACE(1,"copy(%s,%s)",from,to);
    if (noexec)
		return 0;

    if ((fdin = open (from, O_RDONLY | O_BINARY,0)) < 0)
	{
		if(must_exist)
			error (1, errno, "cannot open %s for copying", from);
		else
			return -1;
	}
    if (fstat (fdin, &sb) < 0)
	{
		if(must_exist)
			error (1, errno, "cannot fstat %s", from);
		else
		{
			close(fdin);
			return -1;
		}
	}
	if (force_overwrite && unlink_file (to) && !existence_error (errno))
	    error (1, errno, "unable to remove %s", to);
		
    if ((fdout = open (to, O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0600)) < 0)
		error (1, errno, "cannot create %s for copying", to);
    if (sb.st_size > 0)
    {
	char buf[BUFSIZ];
	int n;

	for (;;) 
	{
	    n = read (fdin, buf, sizeof(buf));
	    if (n == -1)
	    {
#ifdef EINTR
		if (errno == EINTR)
		    continue;
#endif
		error (1, errno, "cannot read file %s for copying", from);
	    }
            else if (n == 0) 
		break;
  
	    if (write(fdout, buf, n) != n) {
		error (1, errno, "cannot write file %s for copying", to);
	    }
	}

#ifdef HAVE_FSYNC
	if (fsync (fdout)) 
	    error (1, errno, "cannot fsync file %s after copying", to);
#endif
    }

    if (close (fdin) < 0) 
	error (0, errno, "cannot close %s", from);
    if (close (fdout) < 0)
	error (1, errno, "cannot close %s", to);

#ifdef UTIME_EXPECTS_WRITABLE
	if (!iswritable (to))
	{
		xchmod (to, 1);
		change_it_back = 1;
	}
#endif  /* UTIME_EXPECTS_WRITABLE  */
    /* now, set the times for the copied file to match those of the original */
    memset ((char *) &t, 0, sizeof (t));
    t.actime = sb.st_atime;
    t.modtime = sb.st_mtime;
    utime (to, &t);
	chmod(to,sb.st_mode);
#ifdef UTIME_EXPECTS_WRITABLE
	if (change_it_back)
		xchmod (to, 0);
#endif  /*  UTIME_EXPECTS_WRITABLE  */
	return 0;
}
Exemplo n.º 20
0
/*
 * Copies "from" to "to", decompressing "from" on the fly
 */
int copy_and_unzip_file (const char *from, const char *to, int force_overwrite, int must_exist)
{
    struct stat sb;
    struct utimbuf t;
    int fdin, fdout;
    z_stream zstr = {0};
    int zstatus;
    char buf[BUFSIZ*10];
    char zbuf[BUFSIZ*20];
    int n;
#ifdef UTIME_EXPECTS_WRITABLE
    int change_it_back = 0;
#endif

	TRACE(1,"copy_and_unzip(%s,%s)",from,to);
    if (noexec)
		return 0;

    if ((fdin = open (from, O_RDONLY | O_BINARY,0)) < 0)
	{
		if(must_exist)
			error (1, errno, "cannot open %s for copying", from);
		else
			return -1;
	}
	if (fstat (fdin, &sb) < 0)
	{
		if(must_exist)
			error (1, errno, "cannot fstat %s", from);
		else
		{
			close(fdin);
			return -1;
		}
	}
	if (force_overwrite && unlink_file (to) && !existence_error (errno))
	    error (1, errno, "unable to remove %s", to);

    if ((fdout = open (to, O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0600))<0)
	    error (1, errno, "cannot create %s for copying", to);

	zstatus = inflateInit2 (&zstr, 47);
	if(zstatus != Z_OK)
	   error(1, 0, "expansion error (INIT): (%d)%s", zstatus,zstr.msg);
     
	if (sb.st_size > 0)
	{
	    for (;;) 
	    {
		n = read (fdin, buf, sizeof(buf));
		if (n == -1)
		{
#ifdef EINTR
		    if (errno == EINTR)
			continue;
#endif
		    error (1, errno, "cannot read file %s for copying", from);
		}
		else if (n == 0) 
		    break;

		zstr.next_in = buf;
		zstr.avail_in = n;	
		while(zstr.avail_in)
		{
			zstr.next_out = zbuf;
			zstr.avail_out = sizeof(zbuf);
			zstatus = inflate (&zstr, 0);
			if(zstatus != Z_OK && zstatus != Z_STREAM_END)	
			error(1,0, "expansion error (inflate): (%d)%s", zstatus,zstr.msg);
			
			n = sizeof(zbuf)-zstr.avail_out;	
			if (n && write(fdout, zbuf, n) != n) {
				error (1, errno, "cannot write file %s for copying", to);
			}
		}
		if(zstatus == Z_STREAM_END)
			break;
		}

#ifdef HAVE_FSYNC
	    if (fsync (fdout)) 
		error (1, errno, "cannot fsync file %s after copying", to);
#endif
	
	}

	zstr.next_out = zbuf;
	zstr.avail_out = sizeof(zbuf);
	zstatus = inflate (&zstr, Z_FINISH);
	if(zstatus != Z_OK && zstatus != Z_STREAM_END)	
	      error(1,0, "expansion error (Z_FINISH): (%d)%s", zstatus,zstr.msg);
	n = sizeof(zbuf)-zstr.avail_out;	
	if (n && write(fdout, zbuf, n) != n) {
	   error (1, errno, "cannot write file %s for copying", to);
	}
	
	zstr.next_in = buf;
	zstr.avail_in = 0;
	zstr.next_out = zbuf;
	zstr.avail_out = sizeof(zbuf);
	zstatus = inflateEnd(&zstr);
	if(zstatus != Z_OK)
	  error(1,0, "expansion error: %s", zstr.msg);

	if (close (fdin) < 0) 
	    error (0, errno, "cannot close %s", from);
	if (close (fdout) < 0)
	    error (1, errno, "cannot close %s", to);

#ifdef UTIME_EXPECTS_WRITABLE
	if (!iswritable (to))
	{
		xchmod (to, 1);
		change_it_back = 1;
	}
#endif  /* UTIME_EXPECTS_WRITABLE  */
    /* now, set the times for the copied file to match those of the original */
    memset ((char *) &t, 0, sizeof (t));
    t.actime = sb.st_atime;
    t.modtime = sb.st_mtime;
    utime (to, &t);
	chmod(to,sb.st_mode);
#ifdef UTIME_EXPECTS_WRITABLE
	if (change_it_back)
		xchmod (to, 0);
#endif  /*  UTIME_EXPECTS_WRITABLE  */
	return 0;
}
Exemplo n.º 21
0
int fix_grub2_inner(lickdir_t *lick, grub2_fix_function function, char original_drive) {
    char drive = original_drive;
    if(!drive) {
        drive = mount_uefi_partition();
        if(!drive) {
            lick->err = strdup2("Could not mount UEFI partition.");
            return 0;
        }
    }

    char *lick_grub = strdup2("?:/efi/lick/" GRUB2_EFI);
    char *lick_shim = strdup2("?:/efi/lick/shim.efi");
    char *lick_mokmanager = strdup2("?:/efi/lick/" MOKMANAGER_EFI);
    char *boot_grub = strdup2("?:/efi/boot/" GRUB2_EFI);
    char *boot_shim = strdup2("?:/efi/boot/shim.efi");
    char *boot_mokmanager = strdup2("?:/efi/boot/" MOKMANAGER_EFI);
    char *boot_file = strdup("?:/efi/boot/bootx64.efi");
    char *boot_file_backup = strdup2("?:/efi/boot/bootx64-orig.efi");
    char *ms_loader = strdup2("?:/efi/microsoft/boot/bootmgfw.efi");
    char *ms_loader_backup = strdup2("?:/efi/microsoft/boot/bootmgfw-backup.efi");
    char *grub_cfg = unix_path(concat_strs(2, lick->drive, "/lickgrub.cfg"));
    char *grub_menu = NULL;

    lick_grub[0] = drive;
    lick_shim[0] = drive;
    lick_mokmanager[0] = drive;
    boot_grub[0] = drive;
    boot_shim[0] = drive;
    boot_mokmanager[0] = drive;
    ms_loader[0] = drive;
    ms_loader_backup[0] = drive;
    boot_file[0] = drive;
    boot_file_backup[0] = drive;

    const char *fatal_warning =
        "WARNING! The fix has only been half applied.\n"
        "The system may not boot when rebooted.\n"
        "Find out why renaming files on the UEFI partition is not working,\n"
        "then move `/EFI/Microsoft` to `/EFI/Microsoft-backup`.";

    grub2_fix_status status = GRUB2_FIX_UNINSTALLED;

    if(path_exists(boot_grub) || path_exists(boot_mokmanager)
            || path_exists(ms_loader_backup)
            || path_exists(boot_file_backup)) {
        if(path_exists(boot_grub) && path_exists(boot_mokmanager)
                && path_exists(ms_loader_backup)
                && path_exists(boot_file_backup))
            status = GRUB2_FIX_INSTALLED;
        else
            status = GRUB2_FIX_PARTLY_INSTALLED;
    }

    int ret = 0;

    if(function == GRUB2_FIX_CHECK) {
        if(status == GRUB2_FIX_INSTALLED)
            ret = 1;
    } else if(status == GRUB2_FIX_PARTLY_INSTALLED)
        lick->err = strdup2("Partial boot fix applied.");
    else if(function == GRUB2_FIX_INSTALL && status == GRUB2_FIX_INSTALLED)
        lick->err = strdup2("Boot fix already applied!");
    else if(function == GRUB2_FIX_UNINSTALL && status == GRUB2_FIX_UNINSTALLED)
        ret = 1;
    else if(function == GRUB2_FIX_INSTALL) {
        /* Steps:
         * 1) Copy `/EFI/LICK/{grubx64,shim,MokManager}.efi` to `/EFI/Boot/`
         * 2) Rename `/EFI/Boot/bootx64.efi` to `bootx64-orig.efi`
         * 3) Rename `/EFI/Boot/shim.efi` to `bootx64.efi`
         * 4) Rename `/EFI/Microsoft/Boot/bootmgfw.efi` to `bootmgfw-backup.efi`
         */
        do {
            int fail = 1;
            do {
                if(!copy_file(boot_grub, lick_grub))
                    break;
                if(!copy_file(boot_shim, lick_shim))
                    break;
                if(!copy_file(boot_mokmanager, lick_mokmanager))
                    break;
                if(!copy_file(boot_file_backup, boot_file))
                    break;

                attrib_t boot_attrs = attrib_open(boot_file);
                if(!replace_file(boot_file, boot_shim)) {
                    attrib_save(boot_file, boot_attrs);
                    lick->err = strdup2("Could not overwrite boot file.");
                    break;
                }
                if(!rename_file(ms_loader_backup, ms_loader)) {
                    // Try to restore the backup.
                    if(!replace_file(boot_file, boot_file_backup)) {
                        // At this point we are stuck with the fix being
                        // half applied. Realistically, this should never occur.
                        attrib_save(boot_file, boot_attrs);
                        lick->err = strdup2(fatal_warning);
                        fail = 0;
                        break;
                    }
                    lick->err = strdup2("Could not rename directory.");
                    break;
                }

                attrib_save(boot_file_backup, boot_attrs);
                fail = 0;
            } while(0);

            if(fail) {
                unlink_file(boot_grub);
                unlink_file(boot_shim);
                unlink_file(boot_mokmanager);
                unlink_file(boot_file_backup);
                if(!lick->err)
                    lick->err = strdup2("Could not copy files on EFI partition.");
                break;
            }

            // Edit grub menu.
            FILE *f = fopen(grub_cfg, "r");
            if(!f) {
                if(!lick->err)
                    lick->err = strdup2("Successfully installed, but could not modify configuration file.");
                break;
            }
            grub_menu = file_to_str(f);
            fclose(f);
            char *grub_menu_lower = lower_str(strdup2(grub_menu));

            // Search for `/efi/microsoft` (case insensitive)
            // and replace with `/efi/microsoft-backup`
            // First, find the number of `/efi/microsoft`
            size_t cnt = 0;
            const char *str = grub_menu_lower;
            const char *needle = "/efi/microsoft/boot/bootmgfw.efi";
            const char *replacement = "/efi/microsoft/boot/bootmgfw-backup.efi";
            for(;;) {
                str = strstr(str, needle);
                if(!str)
                    break;
                ++cnt;
                ++str; // Increment string to find the next occurrance.
            }

            if(cnt > 0) {
                /* Here, there are 3 strings:
                 * - The original menu, grub_menu.
                 *   This is pointed to by start and str_normal.
                 * - The lowercase menu, grub_menu_lower.
                 *   This is pointed to by str.
                 * - The new menu, new_grub_menu.
                 *   This is pointed to by dst.
                 */
                size_t newsize = strlen(grub_menu)
                    + cnt * (strlen(replacement) - strlen(needle))
                    + 1;
                char *new_grub_menu = malloc(newsize);
                char *dst = new_grub_menu;

                const char *start = grub_menu;
                str = grub_menu_lower;
                for(size_t i = 0; i < cnt; ++i) {
                    str = strstr(str, needle);
                    const char *str_normal = str - grub_menu_lower + grub_menu;
                    // Print everything from start to str.
                    size_t len = str_normal - start;
                    memcpy(dst, start, len);
                    dst += len;
                    strcpy(dst, replacement);
                    str += strlen(needle);
                    dst += strlen(replacement);

                    start = str_normal + strlen(needle);
                }
                strcpy(dst, start);
                grub_menu[newsize - 1] = '\0';

                f = fopen(grub_cfg, "w");
                if(!f) {
                    if(!lick->err)
                        lick->err = strdup2("Successfully installed, but could not modify configuration file.");
                    free(new_grub_menu);
                    free(grub_menu_lower);
                    break;
                }
                fprintf(f, "%s", new_grub_menu);
                fclose(f);
                free(new_grub_menu);
                free(grub_menu_lower);
            }
            ret = 1;
        } while(0);
    } else {
        /* Steps:
         * 1) Rename `/EFI/Microsoft/Boot/bootmgfw-backup.efi` to `bootmgfw.efi`
         * 2) Rename `/EFI/Boot/bootx64-orig.efi` to `bootx64.efi`
         * 3) Delete `/EFI/Boot/{grubx64,MokManager}.efi`
         */
        do {
            if(!rename_file(ms_loader, ms_loader_backup)) {
                lick->err = strdup2("Could not rename directory.");
                break;
            }
            attrib_t boot_attrs = attrib_open(boot_file_backup);
            if(!replace_file(boot_file, boot_file_backup)) {
                attrib_save(boot_file_backup, boot_attrs);
                if(!rename_file(ms_loader_backup, ms_loader)) {
                    lick->err = strdup2(fatal_warning);
                    break;
                }
                lick->err = strdup2("Could not replace boot file.");
                break;
            }
            attrib_save(boot_file, boot_attrs);

            unlink_file(boot_grub);
            unlink_file(boot_mokmanager);
            ret = 1;
        } while(0);
    }

    if(!original_drive)
        unmount_uefi_partition(drive);
    free(lick_grub);
    free(lick_shim);
    free(lick_mokmanager);
    free(boot_grub);
    free(boot_shim);
    free(boot_mokmanager);
    free(ms_loader);
    free(ms_loader_backup);
    free(boot_file);
    free(boot_file_backup);
    free(grub_cfg);
    free(grub_menu);
    return ret;
}
Exemplo n.º 22
0
/* Runs the user-defined verification script as part of the commit or import
   process.  This verification is meant to be run whether or not the user
   included the -m attribute.  unlike the do_editor function, this is
   independant of the running of an editor for getting a message.
 */
void
do_verify (char **messagep, const char *repository, List *changes)
{
    int err;
    struct verifymsg_proc_data data;
    struct stat post_stbuf;

    if (current_parsed_root->isremote)
        /* The verification will happen on the server.  */
        return;

    /* FIXME? Do we really want to skip this on noexec?  What do we do
       for the other administrative files?  */
    /* EXPLAIN: Why do we check for repository == NULL here? */
    if (noexec || repository == NULL)
        return;

    /* Get the name of the verification script to run  */

    data.message = *messagep;
    data.fname = NULL;
    data.changes = changes;
    if ((err = Parse_Info (CVSROOTADM_VERIFYMSG, repository,
                           verifymsg_proc, 0, &data)) != 0)
    {
        int saved_errno = errno;
        /* Since following error() exits, delete the temp file now.  */
        if (data.fname != NULL && unlink_file( data.fname ) < 0)
            error (0, errno, "cannot remove %s", data.fname);
        free (data.fname);

        errno = saved_errno;
        error (1, err == -1 ? errno : 0, "Message verification failed");
    }

    /* Return if no temp file was created.  That means that we didn't call any
     * verifymsg scripts.
     */
    if (data.fname == NULL)
        return;

    /* Get the mod time and size of the possibly new log message
     * in always and stat modes.
     */
    if (config->RereadLogAfterVerify == LOGMSG_REREAD_ALWAYS ||
            config->RereadLogAfterVerify == LOGMSG_REREAD_STAT)
    {
        if(stat (data.fname, &post_stbuf) != 0)
            error (1, errno, "cannot find size of temp file %s", data.fname);
    }

    /* And reread the log message in `always' mode or in `stat' mode when it's
     * changed.
     */
    if (config->RereadLogAfterVerify == LOGMSG_REREAD_ALWAYS ||
            (config->RereadLogAfterVerify == LOGMSG_REREAD_STAT &&
             (data.pre_stbuf.st_mtime != post_stbuf.st_mtime ||
              data.pre_stbuf.st_size != post_stbuf.st_size)))
    {
        /* put the entire message back into the *messagep variable */

        if (*messagep) free (*messagep);

        if (post_stbuf.st_size == 0)
            *messagep = NULL;
        else
        {
            char *line = NULL;
            int line_length;
            size_t line_chars_allocated = 0;
            char *p;
            FILE *fp;

            fp = xfopen (data.fname, "r");

            /* On NT, we might read less than st_size bytes,
               but we won't read more.  So this works.  */
            p = *messagep = (char *) xmalloc (post_stbuf.st_size + 1);
            *messagep[0] = '\0';

            for (;;)
            {
                line_length = getline( &line,
                                       &line_chars_allocated,
                                       fp);
                if (line_length == -1)
                {
                    if (ferror (fp))
                        /* Fail in this case because otherwise we will have no
                         * log message
                         */
                        error (1, errno, "cannot read %s", data.fname);
                    break;
                }
                if (strncmp (line, CVSEDITPREFIX, CVSEDITPREFIXLEN) == 0)
                    continue;
                (void) strcpy (p, line);
                p += line_length;
            }
            if (line) free (line);
            if (fclose (fp) < 0)
                error (0, errno, "warning: cannot close %s", data.fname);
        }
    }
    /* Delete the temp file  */
    if (unlink_file (data.fname) < 0)
        error (0, errno, "cannot remove `%s'", data.fname);
    free (data.fname);
}
Exemplo n.º 23
0
/*
 * Builds a temporary file using setup_tmpfile() and invokes the user's
 * editor on the file.  The header garbage in the resultant file is then
 * stripped and the log message is stored in the "message" argument.
 *
 * If REPOSITORY is non-NULL, process rcsinfo for that repository; if it
 * is NULL, use the CVSADM_TEMPLATE file instead.  REPOSITORY should be
 * NULL when running in client mode.
 *
 * GLOBALS
 *   Editor     Set to a default value by configure and overridable using the
 *              -e option to the CVS executable.
 */
void
do_editor (const char *dir, char **messagep, const char *repository,
           List *changes)
{
    static int reuse_log_message = 0;
    char *line;
    int line_length;
    size_t line_chars_allocated;
    char *fname;
    struct stat pre_stbuf, post_stbuf;
    int retcode = 0;

    assert (!current_parsed_root->isremote != !repository);

    if (noexec || reuse_log_message)
        return;

    /* Abort before creation of the temp file if no editor is defined. */
    if (strcmp (Editor, "") == 0)
        error(1, 0, "no editor defined, must use -e or -m");

again:
    /* Create a temporary file.  */
    if( ( fp = cvs_temp_file( &fname ) ) == NULL )
        error( 1, errno, "cannot create temporary file" );

    if (*messagep)
    {
        (void) fputs (*messagep, fp);

        if ((*messagep)[0] == '\0' ||
                (*messagep)[strlen (*messagep) - 1] != '\n')
            (void) fprintf (fp, "\n");
    }
    else
        (void) fprintf (fp, "\n");

    if (repository != NULL)
        /* tack templates on if necessary */
        (void) Parse_Info (CVSROOTADM_RCSINFO, repository, rcsinfo_proc,
                           PIOPT_ALL, NULL);
    else
    {
        FILE *tfp;
        char buf[1024];
        size_t n;
        size_t nwrite;

        /* Why "b"?  */
        tfp = CVS_FOPEN (CVSADM_TEMPLATE, "rb");
        if (tfp == NULL)
        {
            if (!existence_error (errno))
                error (1, errno, "cannot read %s", CVSADM_TEMPLATE);
        }
        else
        {
            while (!feof (tfp))
            {
                char *p = buf;
                n = fread (buf, 1, sizeof buf, tfp);
                nwrite = n;
                while (nwrite > 0)
                {
                    n = fwrite (p, 1, nwrite, fp);
                    nwrite -= n;
                    p += n;
                }
                if (ferror (tfp))
                    error (1, errno, "cannot read %s", CVSADM_TEMPLATE);
            }
            if (fclose (tfp) < 0)
                error (0, errno, "cannot close %s", CVSADM_TEMPLATE);
        }
    }

    (void) fprintf (fp,
                    "%s----------------------------------------------------------------------\n",
                    CVSEDITPREFIX);
    (void) fprintf (fp,
                    "%sEnter Log.  Lines beginning with `%.*s' are removed automatically\n%s\n",
                    CVSEDITPREFIX, CVSEDITPREFIXLEN, CVSEDITPREFIX,
                    CVSEDITPREFIX);
    if (dir != NULL && *dir)
        (void) fprintf (fp, "%sCommitting in %s\n%s\n", CVSEDITPREFIX,
                        dir, CVSEDITPREFIX);
    if (changes != NULL)
        setup_tmpfile (fp, CVSEDITPREFIX, changes);
    (void) fprintf (fp,
                    "%s----------------------------------------------------------------------\n",
                    CVSEDITPREFIX);

    /* finish off the temp file */
    if (fclose (fp) == EOF)
        error (1, errno, "%s", fname);
    if (stat (fname, &pre_stbuf) == -1)
        pre_stbuf.st_mtime = 0;

    /* run the editor */
    run_setup (Editor);
    run_add_arg (fname);
    if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
                             RUN_NORMAL | RUN_SIGIGNORE | RUN_UNSETXID)) != 0)
        error (0, retcode == -1 ? errno : 0, "warning: editor session failed");

    /* put the entire message back into the *messagep variable */

    fp = xfopen (fname, "r");

    if (*messagep)
        free (*messagep);

    if (stat (fname, &post_stbuf) != 0)
        error (1, errno, "cannot find size of temp file %s", fname);

    if (post_stbuf.st_size == 0)
        *messagep = NULL;
    else
    {
        /* On NT, we might read less than st_size bytes, but we won't
           read more.  So this works.  */
        *messagep = (char *) xmalloc (post_stbuf.st_size + 1);
        (*messagep)[0] = '\0';
    }

    line = NULL;
    line_chars_allocated = 0;

    if (*messagep)
    {
        size_t message_len = post_stbuf.st_size + 1;
        size_t offset = 0;
        while (1)
        {
            line_length = getline (&line, &line_chars_allocated, fp);
            if (line_length == -1)
            {
                if (ferror (fp))
                    error (0, errno, "warning: cannot read %s", fname);
                break;
            }
            if (strncmp (line, CVSEDITPREFIX, CVSEDITPREFIXLEN) == 0)
                continue;
            if (offset + line_length >= message_len)
                expand_string (messagep, &message_len,
                               offset + line_length + 1);
            (void) strcpy (*messagep + offset, line);
            offset += line_length;
        }
    }
    if (fclose (fp) < 0)
        error (0, errno, "warning: cannot close %s", fname);

    /* canonicalize emply messages */
    if (*messagep != NULL &&
            (**messagep == '\0' || strcmp (*messagep, "\n") == 0))
    {
        free (*messagep);
        *messagep = NULL;
    }

    if (pre_stbuf.st_mtime == post_stbuf.st_mtime || *messagep == NULL)
    {
        for (;;)
        {
            (void) printf ("\nLog message unchanged or not specified\n");
            (void) printf ("a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs\n");
            (void) printf ("Action: (abort) ");
            (void) fflush (stdout);
            line_length = getline (&line, &line_chars_allocated, stdin);
            if (line_length < 0)
            {
                error (0, errno, "cannot read from stdin");
                if (unlink_file (fname) < 0)
                    error (0, errno,
                           "warning: cannot remove temp file %s", fname);
                error (1, 0, "aborting");
            }
            else if (line_length == 0
                     || *line == '\n' || *line == 'a' || *line == 'A')
            {
                if (unlink_file (fname) < 0)
                    error (0, errno, "warning: cannot remove temp file %s", fname);
                error (1, 0, "aborted by user");
            }
            if (*line == 'c' || *line == 'C')
                break;
            if (*line == 'e' || *line == 'E')
                goto again;
            if (*line == '!')
            {
                reuse_log_message = 1;
                break;
            }
            (void) printf ("Unknown input\n");
        }
    }
    if (line)
        free (line);
    if (unlink_file (fname) < 0)
        error (0, errno, "warning: cannot remove temp file %s", fname);
    free (fname);
}
Exemplo n.º 24
0
/* ARGSUSED */
static int remove_fileproc (void *callerdat, struct file_info *finfo)
{
    Vers_TS *vers;

    if (force)
    {
	if (!noexec)
	{
	    if ( CVS_UNLINK (finfo->file) < 0 && ! existence_error (errno))
	    {
		error (0, errno, "unable to remove %s", fn_root(finfo->fullname));
	    }
	}
	/* else FIXME should probably act as if the file doesn't exist
	   in doing the following checks.  */
    }

    vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0, 0);

    if (vers->ts_user && (!vers->vn_user || strcmp(vers->vn_user,"0")))
    {
	existing_files++;
	if (!quiet)
	    error (0, 0, "file `%s' still in working directory",
		   fn_root(finfo->fullname));
    }
    else if (vers->vn_user == NULL)
    {
	if (!quiet)
	    error (0, 0, "nothing known about `%s'", fn_root(finfo->fullname));
    }
    else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
    {
	char *fname;

	/*
	 * It's a file that has been added, but not commited yet. So,
	 * remove the ,t file for it and scratch it from the
	 * entries file.  */
	Scratch_Entry (finfo->entries, finfo->file);
	fname = (char*)xmalloc (strlen (finfo->file)
			 + sizeof (CVSADM)
			 + sizeof (CVSEXT_LOG)
			 + 10);
	(void) sprintf (fname, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
	if (unlink_file (fname) < 0
	    && !existence_error (errno))
	    error (0, errno, "cannot remove %s", CVSEXT_LOG);
	if (!quiet)
	    error (0, 0, "removed `%s'", fn_root(finfo->fullname));

#ifdef SERVER_SUPPORT
	if (server_active)
	    server_checked_in (finfo->file, finfo->update_dir, finfo->repository);
#endif
	xfree (fname);
    }
    else if (vers->vn_user[0] == '-')
    {
	if (!quiet)
	    error (0, 0, "file `%s' already scheduled for removal",
		   fn_root(finfo->fullname));
    }
    else if (vers->tag != NULL && ((isdigit ((unsigned char) *vers->tag)) || !RCS_isbranch(finfo->rcs, vers->tag)))
    {
	/* Commit will just give an error, and so there seems to be
	   little reason to allow the remove.  I mean, conflicts that
	   arise out of parallel development are one thing, but conflicts
	   that arise from sticky tags are quite another.  */
	error (0, 0, "\
cannot remove file `%s' which has a sticky tag of `%s'",
	       fn_root(finfo->fullname), vers->tag);
	bad_files++;
    }
    else
    {
	char *fname;

	/* Re-register it with a negative version number.  */
	fname = (char*)xmalloc (strlen (vers->vn_user) + 5);
	(void) strcpy (fname, "-");
	(void) strcat (fname, vers->vn_user);
	Register (finfo->entries, finfo->file, fname, vers->ts_rcs, vers->options,
		  vers->tag, vers->date, vers->ts_conflict, NULL, NULL, vers->tt_rcs, vers->edit_revision, vers->edit_tag, vers->edit_bugid, NULL);
	if (!quiet)
	    error (0, 0, "scheduling `%s' for removal", fn_root(finfo->fullname));
	removed_files++;

#ifdef SERVER_SUPPORT
	if (server_active)
	    server_checked_in (finfo->file, finfo->update_dir, finfo->repository);
#endif
	xfree (fname);
    }

    freevers_ts (&vers);
    return (0);
}
Exemplo n.º 25
0
int
RCS_merge (RCSNode *rcs, const char *path, const char *workfile,
           const char *options, const char *rev1, const char *rev2)
{
    char *xrev1, *xrev2;
    char *tmp1, *tmp2;
    char *diffout = NULL;
    int retval;

    if (options != NULL && options[0] != '\0')
      assert (options[0] == '-' && options[1] == 'k');

    cvs_output ("RCS file: ", 0);
    cvs_output (rcs->print_path, 0);
    cvs_output ("\n", 1);

    /* Calculate numeric revision numbers from rev1 and rev2 (may be
       symbolic).
       FIXME - No they can't.  Both calls to RCS_merge are passing in
       numeric revisions.  */
    xrev1 = RCS_gettag (rcs, rev1, 0, NULL);
    xrev2 = RCS_gettag (rcs, rev2, 0, NULL);
    assert (xrev1 && xrev2);

    /* Check out chosen revisions.  The error message when RCS_checkout
       fails is not very informative -- it is taken verbatim from RCS 5.7,
       and relies on RCS_checkout saying something intelligent upon failure. */
    cvs_output ("retrieving revision ", 0);
    cvs_output (xrev1, 0);
    cvs_output ("\n", 1);

    tmp1 = cvs_temp_name();
    if (RCS_checkout (rcs, NULL, xrev1, rev1, options, tmp1, NULL, NULL))
    {
	cvs_outerr ("rcsmerge: co failed\n", 0);
	exit (EXIT_FAILURE);
    }

    cvs_output ("retrieving revision ", 0);
    cvs_output (xrev2, 0);
    cvs_output ("\n", 1);

    tmp2 = cvs_temp_name();
    if (RCS_checkout (rcs, NULL, xrev2, rev2, options, tmp2, NULL, NULL))
    {
	cvs_outerr ("rcsmerge: co failed\n", 0);
	exit (EXIT_FAILURE);
    }

    /* Merge changes. */
    cvs_output ("Merging differences between ", 0);
    cvs_output (xrev1, 0);
    cvs_output (" and ", 0);
    cvs_output (xrev2, 0);
    cvs_output (" into ", 0);
    cvs_output (workfile, 0);
    cvs_output ("\n", 1);

    /* Remember that the first word in the `call_diff_setup' string is used now
       only for diagnostic messages -- CVS no longer forks to run diff3. */
    diffout = cvs_temp_name();
    call_diff_setup ("diff3", 0, NULL);
    call_diff_add_arg ("-E");
    call_diff_add_arg ("-am");

    call_diff_add_arg ("-L");
    call_diff_add_arg (workfile);
    call_diff_add_arg ("-L");
    call_diff_add_arg (xrev1);
    call_diff_add_arg ("-L");
    call_diff_add_arg (xrev2);

    call_diff_add_arg ("--");
    call_diff_add_arg (workfile);
    call_diff_add_arg (tmp1);
    call_diff_add_arg (tmp2);

    retval = call_diff3 (diffout);

    if (retval == 1)
	cvs_outerr ("rcsmerge: warning: conflicts during merge\n", 0);
    else if (retval == 2)
	exit (EXIT_FAILURE);

    if (diffout)
	copy_file (diffout, workfile);

    /* Clean up. */
    {
	int save_noexec = noexec;
	noexec = 0;
	if (unlink_file (tmp1) < 0)
	{
	    if (!existence_error (errno))
		error (0, errno, "cannot remove temp file %s", tmp1);
	}
	free (tmp1);
	if (unlink_file (tmp2) < 0)
	{
	    if (!existence_error (errno))
		error (0, errno, "cannot remove temp file %s", tmp2);
	}
	free (tmp2);
	if (diffout)
	{
	    if (unlink_file (diffout) < 0)
	    {
		if (!existence_error (errno))
		    error (0, errno, "cannot remove temp file %s", diffout);
	    }
	    free (diffout);
	}
	free (xrev1);
	free (xrev2);
	noexec = save_noexec;
    }

    return retval;
}
Exemplo n.º 26
0
/*ARGSUSED*/
static int release_delete_fileproc (void *callerdat, struct file_info *finfo)
{
	unlink_file(finfo->file);
	return 0;
}
Exemplo n.º 27
0
/* This checks relative caches in dir/.thumbnails and
 * removes them if they have no source counterpart.
 */
gint cache_maintain_dir(FileData *dir_fd, gint recursive, gint clear)
{
	GList *list = NULL;
	gchar *cachedir;
	FileData *cachedir_fd;
	gboolean still_have_a_file = FALSE;
	GList *work;

	cachedir = g_build_filename(dir, GQ_CACHE_LOCAL_THUMB, NULL);
	cachedir_fd = file_data_new_simple(cachedir);
	g_free(cachedir);

	filelist_read(cachedir_fd, &list, NULL);
	work = list;

	while (work)
		{
		FileData *fd;
		gchar *source;

		fd = work->data;
		work = work->next;

		source = g_build_filename(dir->path, fd->name, NULL);

		if (clear ||
		    extension_truncate(source, GQ_CACHE_EXT_THUMB) ||
		    extension_truncate(source, GQ_CACHE_EXT_SIM))
			{
			if (!clear && isfile(source))
				{
				still_have_a_file = TRUE;
				}
			else
				{
				if (!unlink_file(fd->path))
					{
					DEBUG_1("Failed to remove cache file %s", fd->path);
					still_have_a_file = TRUE;
					}
				}
			}
		else
			{
			still_have_a_file = TRUE;
			}
		g_free(source);
		}

	filelist_free(list);
	file_data_unref(cachedir_fd);

	if (recursive)
		{
		list = NULL;

		filelist_read(dir_fd, NULL, &list);
		work = list;
		while (work)
			{
			FileData *fd = work->data;
			work = work->next;

			still_have_a_file |= cache_maintain_dir(fd->path, recursive, clear);
			}

		filelist_free(list);
		}

	return still_have_a_file;
}
Exemplo n.º 28
0
/* This checks all files in ~/GQ_RC_DIR/thumbnails and
 * removes them if thay have no source counterpart.
 * (this assumes all cache files have an extension of 4 chars including '.')
 */
gint cache_maintain_home_dir(const gchar *dir, gint recursive, gint clear)
{
	gchar *base;
	gint base_length;
	GList *dlist = NULL;
	FileData *dir_fd;
	GList *flist = NULL;
	gboolean still_have_a_file = FALSE;

	DEBUG_1("maintainance check: %s", dir);

	base_length = strlen(homedir()) + strlen("/") + strlen(GQ_CACHE_RC_THUMB);
	base = g_strconcat(homedir(), "/", GQ_CACHE_RC_THUMB, dir, NULL);
	dir_fd = file_data_new_simple(base);
	g_free(base);

	if (filelist_read(dir_fd, &flist, &dlist))
		{
		GList *work;

		work = dlist;
		while (work)
			{
			FileData *fd = work->data;
			if (recursive && strlen(fd->path) > base_length &&
			    !cache_maintain_home_dir(fd->path + base_length, recursive, clear))
				{
				DEBUG_1("Deleting thumb dir: %s", fd->path);
				if (!rmdir_utf8(fd->path))
					{
					log_printf("Unable to delete dir: %s\n", fd->path);
					}
				}
			else
				{
				still_have_a_file = TRUE;
				}
			work = work->next;
			}

		work = flist;
		while (work)
			{
			FileData *fd = work->data;
			gchar *path = g_strdup(fd->path);
			gchar *dot;

			dot = extension_find_dot(path);

			if (dot) *dot = '\0';
			if (clear ||
			    (strlen(path) > base_length && !isfile(path + base_length)) )
				{
				if (dot) *dot = '.';
				if (!unlink_file(path)) log_printf("failed to delete:%s\n", path);
				}
			else
				{
				still_have_a_file = TRUE;
				}
			g_free(path);

			work = work->next;
			}
		}

	filelist_free(dlist);
	filelist_free(flist);
	file_data_unref(dir_fd);

	return still_have_a_file;
}
Exemplo n.º 29
0
static gboolean cache_maintain_home_cb(gpointer data)
{
	CMData *cm = data;
	GList *dlist = NULL;
	GList *list = NULL;
	FileData *fd;
	gboolean just_done = FALSE;
	gboolean still_have_a_file = TRUE;
	gsize base_length;
	const gchar *cache_folder;

	if (cm->metadata)
		{
		cache_folder = get_metadata_cache_dir();
		}
	else
		{
		cache_folder = get_thumbnails_cache_dir();
		}

	base_length = strlen(cache_folder);

	if (!cm->list)
		{
		DEBUG_1("purge chk done.");
		cm->idle_id = 0;
		cache_maintain_home_stop(cm);
		return FALSE;
		}

	fd = cm->list->data;

	DEBUG_1("purge chk (%d) \"%s\"", (cm->clear && !cm->metadata), fd->path);

	if (g_list_find(cm->done_list, fd) == NULL)
		{
		cm->done_list = g_list_prepend(cm->done_list, fd);

		if (filelist_read(fd, &list, &dlist))
			{
			GList *work;

			just_done = TRUE;
			still_have_a_file = FALSE;

			work = list;
			while (work)
				{
				FileData *fd_list = work->data;
				gchar *path_buf = g_strdup(fd_list->path);
				gchar *dot;

				dot = extension_find_dot(path_buf);

				if (dot) *dot = '\0';
				if ((!cm->metadata && cm->clear) ||
				    (strlen(path_buf) > base_length && !isfile(path_buf + base_length)) )
					{
					if (dot) *dot = '.';
					if (!unlink_file(path_buf)) log_printf("failed to delete:%s\n", path_buf);
					}
				else
					{
					still_have_a_file = TRUE;
					}
				g_free(path_buf);
				work = work->next;
				}
			}
		}
	filelist_free(list);

	cm->list = g_list_concat(dlist, cm->list);

	if (cm->list && g_list_find(cm->done_list, cm->list->data) != NULL)
		{
		/* check if the dir is empty */

		if (cm->list->data == fd && just_done)
			{
			if (!still_have_a_file && !dlist && cm->list->next && !rmdir_utf8(fd->path))
				{
				log_printf("Unable to delete dir: %s\n", fd->path);
				}
			}
		else
			{
			/* must re-check for an empty dir */
			if (isempty(fd->path) && cm->list->next && !rmdir_utf8(fd->path))
				{
				log_printf("Unable to delete dir: %s\n", fd->path);
				}
			}

		fd = cm->list->data;
		cm->done_list = g_list_remove(cm->done_list, fd);
		cm->list = g_list_remove(cm->list, fd);
		file_data_unref(fd);
		}

	if (cm->list)
		{
		const gchar *buf;

		fd = cm->list->data;
		if (strlen(fd->path) > base_length)
			{
			buf = fd->path + base_length;
			}
		else
			{
			buf = "...";
			}
		gtk_entry_set_text(GTK_ENTRY(cm->entry), buf);
		}

	return TRUE;
}
Exemplo n.º 30
0
/**
 * @brief Remove a package's files, optionally skipping its replacement's
 * files.
 *
 * @param handle the context handle
 * @param oldpkg package to remove
 * @param newpkg package to replace \a oldpkg (optional)
 * @param targ_count current index within the transaction (1-based)
 * @param pkg_count the number of packages affected by the transaction
 *
 * @return 0 on success, -1 if alpm lacks permission to delete some of the
 * files, >0 the number of files alpm was unable to delete
 */
static int remove_package_files(alpm_handle_t *handle,
		alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg,
		size_t targ_count, size_t pkg_count)
{
	alpm_list_t *skip_remove;
	alpm_filelist_t *filelist;
	size_t i;
	int err = 0;
	int nosave = handle->trans->flags & ALPM_TRANS_FLAG_NOSAVE;

	if(newpkg) {
		alpm_filelist_t *newfiles;
		alpm_list_t *b;
		skip_remove = alpm_list_join(
				alpm_list_strdup(handle->trans->skip_remove),
				alpm_list_strdup(handle->noupgrade));
		/* Add files in the NEW backup array to the skip_remove array
		 * so this removal operation doesn't kill them */
		/* old package backup list */
		newfiles = alpm_pkg_get_files(newpkg);
		for(b = alpm_pkg_get_backup(newpkg); b; b = b->next) {
			const alpm_backup_t *backup = b->data;
			/* safety check (fix the upgrade026 pactest) */
			if(!alpm_filelist_contains(newfiles, backup->name)) {
				continue;
			}
			_alpm_log(handle, ALPM_LOG_DEBUG, "adding %s to the skip_remove array\n",
					backup->name);
			skip_remove = alpm_list_add(skip_remove, strdup(backup->name));
		}
	} else {
		skip_remove = alpm_list_strdup(handle->trans->skip_remove);
	}

	filelist = alpm_pkg_get_files(oldpkg);
	for(i = 0; i < filelist->count; i++) {
		alpm_file_t *file = filelist->files + i;
		if(!can_remove_file(handle, file, skip_remove)) {
			_alpm_log(handle, ALPM_LOG_DEBUG,
					"not removing package '%s', can't remove all files\n",
					oldpkg->name);
			FREELIST(skip_remove);
			RET_ERR(handle, ALPM_ERR_PKG_CANT_REMOVE, -1);
		}
	}

	_alpm_log(handle, ALPM_LOG_DEBUG, "removing %zd files\n", filelist->count);

	if(!newpkg) {
		/* init progress bar, but only on true remove transactions */
		PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, oldpkg->name, 0,
				pkg_count, targ_count);
	}

	/* iterate through the list backwards, unlinking files */
	for(i = filelist->count; i > 0; i--) {
		alpm_file_t *file = filelist->files + i - 1;
		if(unlink_file(handle, oldpkg, newpkg, file, skip_remove, nosave) < 0) {
			err++;
		}

		if(!newpkg) {
			/* update progress bar after each file */
			int percent = ((filelist->count - i) * 100) / filelist->count;
			PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, oldpkg->name,
					percent, pkg_count, targ_count);
		}
	}
	FREELIST(skip_remove);

	if(!newpkg) {
		/* set progress to 100% after we finish unlinking files */
		PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, oldpkg->name, 100,
				pkg_count, targ_count);
	}

	return err;
}