Esempio n. 1
0
static int recover_finishing(struct async *as,
	struct sdirs *sdirs, struct conf **cconfs)
{
	int r;
	char msg[128]="";
	struct asfd *asfd=as->asfd;
	logp("Found finishing symlink - attempting to complete prior backup!\n");

	snprintf(msg, sizeof(msg),
		"Now finalising previous backup of client. "
		"Please try again later.");
	asfd->write_str(asfd, CMD_ERROR, msg);

	// Do not need the client connected any more.
	// Disconnect.
	logp("Disconnect from client.\n");
	as->asfd_remove(as, asfd);
	asfd_close(asfd);

	switch(get_protocol(cconfs))
	{
		case PROTO_1:
			r=backup_phase4_server_protocol1(sdirs, cconfs);
			break;
		case PROTO_2:
		default:
			r=backup_phase4_server_protocol2(sdirs, cconfs);
			break;
	}
	if(r)
	{
		logp("Problem with prior backup. Please check the client log on the server.");
		return -1;
	}
	logp("Prior backup completed OK.\n");

	// Move the symlink to indicate that we are now in the end
	// phase.
	// FIX THIS: Check whether the rename race condition is recoverable
	// here.
	if(do_rename(sdirs->finishing, sdirs->current)) return -1;
	return 0;
}
Esempio n. 2
0
static int do_rename_w(const char *a, const char *b,
	const char *cname, struct bu *bu)
{
	int ret=-1;
	char *target=NULL;
	char new_name[256]="";
	snprintf(new_name, sizeof(new_name), "%s-%s", cname, bu->basename);
	if(!(target=prepend_s(b, new_name))
	  || build_path_w(target))
		goto end;
	if(do_rename(a, target))
	{
		logp("Error when trying to rename for delete %s\n", a);
		goto end;
	}
	ret=0;
end:
	free_w(&target);
	return ret;
}
Esempio n. 3
0
int make_backup(char *fname)
{
	char fnamebak[MAXPATHLEN];
	if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
		rprintf(FERROR,"backup filename too long\n");
		return 0;
	}

	slprintf(fnamebak,sizeof(fnamebak),"%s%s",fname,backup_suffix);
	if (do_rename(fname,fnamebak) != 0) {
		/* cygwin (at least version b19) reports EINVAL */
		if (errno != ENOENT && errno != EINVAL) {
			rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
			return 0;
		}
	} else if (verbose > 1) {
		rprintf(FINFO,"backed up %s to %s\n",fname,fnamebak);
	}
	return 1;
}
Esempio n. 4
0
int main(int argc, char *argv[])
{
	char *init_cwd;
	pid_t pid;
	int status;
	int ret = 1;

	if (argc != 2) {
		printf("Usage: %s <dir>\n", argv[0]);
		exit(1);
	}

	init_cwd = argv[1];
	ret = chdir(init_cwd);
	if (ret < 0) {
		perror("chdir failed");
		exit(1);
	}

	if (signal(SIGALRM, sigproc) == SIG_ERR) {
		perror("signal failed");
		exit(1);
	}

	alarm(TIMEOUT);

	pid = fork();
	if (pid < 0) {
		perror("fork failed");
		exit(1);
	} else if (pid == 0) {
		do_rename("t_getcwd_testfile");
	} else {
		ret = test_getcwd(init_cwd);
		kill(pid, SIGTERM);
		waitpid(pid, &status, 0);
	}

	exit(ret);
}
Esempio n. 5
0
File: bedup.c Progetto: kaptk2/burp
/* Make it atomic by linking to a temporary file, then moving it into place. */
static int do_hardlink(struct file *o, struct file *n, const char *ext)
{
	int ret=-1;
	char *tmppath=NULL;
	if(!(tmppath=prepend(o->path, ext, "")))
	{
		log_out_of_memory(__func__);
		goto end;
	}
	if(link(n->path, tmppath))
	{
		logp("Could not hardlink %s to %s: %s\n", tmppath, n->path,
			strerror(errno));
		goto end;
	}
	if((ret=do_rename(tmppath, o->path)))
		goto end;
	ret=0;
end:
	free_w(&tmppath);
	return ret;
}
Esempio n. 6
0
/* Make it atomic by linking to a temporary file, then moving it into place. */
static int do_hardlink(struct file *o, struct file *n, const char *ext)
{
	char *tmppath=NULL;
	if(!(tmppath=prepend(o->path, ext, "")))
	{
		logp("out of memory\n");
		return -1;
	}
	if(link(n->path, tmppath))
	{
		logp("Could not hardlink %s to %s: %s\n", tmppath, n->path,
			strerror(errno));
		free(tmppath);
		return -1;
	}
	if(do_rename(tmppath, o->path))
	{
		free(tmppath);
		return -1;
	}
	free(tmppath);
	return 0;
}
Esempio n. 7
0
static int merge_into_global_sparse(const char *sparse, const char *global,
	struct conf **confs)
{
	int ret=-1;
	char *tmpfile=NULL;
	struct stat statp;
	char *lockfile=NULL;
	struct lock *lock=NULL;
	const char *globalsrc=NULL;
	
	if(!(tmpfile=prepend_n(global, "tmp", strlen("tmp"), ".")))
		goto end;

	// Get a lock before messing with the global sparse index.
	if(!(lockfile=prepend_n(global, "lock", strlen("lock"), "."))
	  || !(lock=lock_alloc_and_init(lockfile)))
		goto end;

	if(try_to_get_lock(lock)) goto end;

	if(!lstat(global, &statp)) globalsrc=global;

	if(merge_sparse_indexes(sparse, globalsrc, tmpfile, confs))
		goto end;

	// FIX THIS: nasty race condition needs to be recoverable.
	if(do_rename(tmpfile, global)) goto end;

	ret=0;
end:
	lock_release(lock);
	lock_free(&lock);
	if(lockfile) free(lockfile);
	if(tmpfile) free(tmpfile);
	return ret;
}
Esempio n. 8
0
int compress_file(const char *src, const char *dst, struct config *cconf)
{
	char *dsttmp=NULL;
	pid_t pid=getpid();
	char p[12]="";
	snprintf(p, sizeof(p), "%d", (int)pid);

	if(!(dsttmp=prepend(dst, p, strlen(p), 0 /* no slash */)))
		return -1;
	
	// Need to compress the log.
	logp("Compressing %s to %s...\n", src, dst);
	if(compress(src, dsttmp, cconf)
	  || do_rename(dsttmp, dst))
	{
		unlink(dsttmp);
		free(dsttmp);
		return -1;
	}
	// succeeded - get rid of the uncompressed version
	unlink(src);
	free(dsttmp);
	return 0;
}
Esempio n. 9
0
int
main(int argc, char **argv)
{
  int a;

  if (argc == 1)
    {
      printf("usage: %s file [file ...]\n", argv[0]);
      exit(1);
    }

  for (a = 1;a < argc;a++)
    {
      if (strcmp("-v", argv[a]) == 0)
	{
	  _verbose++;
	  continue;
	}

      do_rename(argv[a]);
    }

  return 0;
}
Esempio n. 10
0
int main(void)
{
	char dir_src[PATH_MAX];
	char dir_dst[PATH_MAX];

	EXPECT_ZERO(get_tempdir(dir_src, PATH_MAX, 0755));
	EXPECT_ZERO(register_tempdir_for_cleanup(dir_src));
	EXPECT_ZERO(get_tempdir(dir_dst, PATH_MAX, 0755));
	EXPECT_ZERO(register_tempdir_for_cleanup(dir_dst));

	/* test rename /src/a -> /dst/m, a as file, m as file */
	EXPECT_ZERO(do_touch2(dir_src, "a"));
	EXPECT_ZERO(do_touch2(dir_dst, "m"));
	EXPECT_ZERO(do_rename(dir_src, "a", dir_dst, "m"));

	/* test rename /src/b -> /dst/n, b as file, n as dir */
	EXPECT_ZERO(do_touch2(dir_src, "b"));
	EXPECT_ZERO(do_test_mkdir(dir_dst, "n"));
	EXPECT_EQ(do_rename(dir_src, "b", dir_dst, "n"), -EISDIR);

	/* test rename /src/c -> /dst/o, c as dir, o as file */
	EXPECT_ZERO(do_test_mkdir(dir_src, "c"));
	EXPECT_ZERO(do_touch2(dir_dst, "o"));
	EXPECT_EQ(do_rename(dir_src, "c", dir_dst, "o"), -ENOTDIR);

	/* test rename /src/d -> /dst/p, d as dir, p as dir */
	EXPECT_ZERO(do_test_mkdir(dir_src, "d"));
	EXPECT_ZERO(do_test_mkdir(dir_dst, "p"));
	EXPECT_ZERO(do_rename(dir_src, "d", dir_dst, "p"));

	/* test rename /src/e -> /dst/q, e as file, q as nonexistent */
	EXPECT_ZERO(do_touch2(dir_src, "e"));
	EXPECT_ZERO(do_rename(dir_src, "e", dir_dst, "q"));

	/* test rename /src/f -> /dst/r, f as dir, r as nonexistent */
	EXPECT_ZERO(do_test_mkdir(dir_src, "f"));
	EXPECT_ZERO(do_rename(dir_src, "f", dir_dst, "r"));

	return 0;
}
Esempio n. 11
0
/* Return 1 for everything OK, signed and returned, -1 for error, 0 for
   nothing done. */
int ca_client_setup(struct config *conf, struct cntr *p1cntr)
{
	char cmd;
	int ret=-1;
	size_t len=0;
	char *buf=NULL;
	char csr_path[256]="";
	char ssl_cert_tmp[512]="";
	char ssl_cert_ca_tmp[512]="";
	struct stat statp;

	// Do not continue if we have none of the following things set.
	if(  !conf->ca_burp_ca
	  || !conf->ca_csr_dir
	  || !conf->ssl_cert_ca
	  || !conf->ssl_cert
	  || !conf->ssl_key
	// Do not try to get a new certificate if we already have a
	// key.
	  || !lstat(conf->ssl_key, &statp))
	{
		if(async_write_str(CMD_GEN, "nocsr")
		  || async_read_expect(CMD_GEN, "nocsr ok"))
		{
			logp("problem reading from server nocsr\n");
			return -1;
		}
		logp("nocsr ok\n");
		return 0;
	}

	// Tell the server we want to do a signing request.
	if(async_write_str(CMD_GEN, "csr"))
		return -1;

	if(async_rw_ensure_read(&cmd, &buf, &len, '\0', NULL, 0))
	{
		logp("problem reading from server csr\n");
		goto end;
	}
	if(cmd!=CMD_GEN || strncmp(buf, "csr ok:", strlen("csr ok:")))
	{
		logp("unexpected command from server: %c:%s\n", cmd, buf);
		goto end;
	}
	// The server appends its name after 'csr ok:'
	if(conf->ssl_peer_cn) free(conf->ssl_peer_cn);
	if(!(conf->ssl_peer_cn=strdup(buf+strlen("csr ok:"))))
	{
		logp("out of memory\n");
		goto end;
	}

	logp("Server will sign a certificate request\n");

	// First need to generate a client key and a certificate signing
	// request.
	snprintf(csr_path, sizeof(csr_path), "%s/%s.csr",
		conf->ca_csr_dir, conf->cname);
	if(generate_key_and_csr(conf, csr_path)) goto end;

	// Then copy the csr to the server.
	if(send_a_file(csr_path, p1cntr)) goto end;

	snprintf(ssl_cert_tmp, sizeof(ssl_cert_tmp), "%s.%d",
		conf->ssl_cert, getpid());
	snprintf(ssl_cert_ca_tmp, sizeof(ssl_cert_ca_tmp), "%s.%d",
		conf->ssl_cert_ca, getpid());

	// The server will then sign it, and give it back.
	if(receive_a_file(ssl_cert_tmp, p1cntr)) goto end;

	// The server will also send the CA certificate.
	if(receive_a_file(ssl_cert_ca_tmp, p1cntr)) goto end;

	if(do_rename(ssl_cert_tmp, conf->ssl_cert)
	  || do_rename(ssl_cert_ca_tmp, conf->ssl_cert_ca))
		goto end;

	// Need to rewrite our configuration file to contain the server
	// name (ssl_peer_cn)
	if(rewrite_client_conf(conf)) goto end;

	// My goodness, everything seems to have gone OK. Stand back!
	ret=1;
end:
	if(buf) free(buf);
	if(ret<0)
	{
		// On error, remove any possibly newly created files, so that
		// this function might run again on another go.
		unlink(csr_path);
		unlink(conf->ssl_key);
		unlink(conf->ssl_cert);
		unlink(conf->ssl_cert_ca);
		unlink(ssl_cert_tmp);
		unlink(ssl_cert_ca_tmp);
	}
	return ret;
}
Esempio n. 12
0
/*
 * Try to revert everything we have done in __rename_all and __rename_all_unlink
 */
static int __rename_all_revert(struct inode *old_dir, struct dentry *old_dentry,
			       struct inode *new_dir, struct dentry *new_dentry,
			       fd_set * success_mask, struct rename_info *info)
{
	int bindex;

	int err;
	int eio = 0;

	print_entry_location();

	for (bindex = info->old_bstart; bindex <= info->old_bend; bindex++) {
		if (!FD_ISSET(bindex, success_mask))
			continue;

		err = unionfs_refresh_hidden_dentry(new_dentry, bindex);
		if (err) {
			printk(KERN_WARNING "Revert failed in rename: "
			       "the new refresh failed.\n");
			eio = -EIO;
		}

		err = unionfs_refresh_hidden_dentry(old_dentry, bindex);
		if (err) {
			printk(KERN_WARNING "Revert failed in rename: "
			       "the old refresh failed.\n");
			eio = -EIO;
			continue;
		}

		if (!dtohd_index(new_dentry, bindex)
		    || !dtohd_index(new_dentry, bindex)->d_inode) {
			printk(KERN_WARNING "Revert failed in rename: "
			       "the object disappeared from under us!\n");
			eio = -EIO;
			continue;
		}

		if (dtohd_index(old_dentry, bindex)
		    && dtohd_index(old_dentry, bindex)->d_inode) {
			printk(KERN_WARNING "Revert failed in rename: "
			       "the object was created underneath us!\n");
			eio = -EIO;
			continue;
		}

		err =
		    do_rename(new_dir, new_dentry, old_dir, old_dentry, bindex,
			      NULL);
		/* If we can't fix it, then we cop-out with -EIO. */
		if (err) {
			printk(KERN_WARNING "Revert failed in rename!\n");
			eio = -EIO;
		}

		err = unionfs_refresh_hidden_dentry(new_dentry, bindex);
		if (err)
			eio = -EIO;
		err = unionfs_refresh_hidden_dentry(old_dentry, bindex);
		if (err)
			eio = -EIO;
	}

	print_exit_status(eio);
	return eio;
}
Esempio n. 13
0
// Combine the phase1 and phase2 files into a new manifest.
int backup_phase3_server_all(struct sdirs *sdirs, struct conf **confs)
{
	int ret=-1;
	int pcmp=0;
	struct blk *blk=NULL;
	struct sbuf *usb=NULL;
	struct sbuf *csb=NULL;
	char *manifesttmp=NULL;
	struct manio *newmanio=NULL;
	struct manio *chmanio=NULL;
	struct manio *unmanio=NULL;
	enum protocol protocol=get_protocol(confs);
	struct cntr *cntr=get_cntr(confs);
	const char *rmanifest_relative=NULL;

	logp("Begin phase3 (merge manifests)\n");

	if(protocol==PROTO_2)
		rmanifest_relative=get_rmanifest_relative(sdirs, confs);

	if(!(manifesttmp=get_tmp_filename(sdirs->manifest))
	  || !(newmanio=manio_open_phase3(manifesttmp,
		comp_level(get_int(confs[OPT_COMPRESSION])),
		protocol, rmanifest_relative))
	  || !(chmanio=manio_open_phase2(sdirs->changed, "rb", protocol))
	  || !(unmanio=manio_open_phase2(sdirs->unchanged, "rb", protocol))
	  || !(usb=sbuf_alloc(protocol))
	  || !(csb=sbuf_alloc(protocol)))
		goto end;

	while(chmanio || unmanio)
	{
		if(!blk && !(blk=blk_alloc())) goto end;

		if(unmanio
		  && !usb->path.buf)
		{
			switch(manio_read(unmanio, usb))
			{
				case -1: goto end;
				case 1: manio_close(&unmanio);
			}
		}

		if(chmanio
		  && !csb->path.buf)
		{
			switch(manio_read(chmanio, csb))
			{
				case -1: goto end;
				case 1: manio_close(&chmanio);
			}
		}

		if(usb->path.buf && !csb->path.buf)
		{
			if(write_status(CNTR_STATUS_MERGING,
				usb->path.buf, cntr)) goto end;
			switch(manio_copy_entry(
				usb, usb, &blk, unmanio, newmanio))
			{
				case -1: goto end;
				case 1: manio_close(&unmanio);
			}
		}
		else if(!usb->path.buf && csb->path.buf)
		{
			if(write_status(CNTR_STATUS_MERGING,
				csb->path.buf, cntr)) goto end;
			switch(manio_copy_entry(
				csb, csb, &blk, chmanio, newmanio))
			{
				case -1: goto end;
				case 1: manio_close(&chmanio);
			}
		}
		else if(!usb->path.buf && !csb->path.buf)
		{
			continue;
		}
		else if(!(pcmp=sbuf_pathcmp(usb, csb)))
		{
			// They were the same - write one.
			if(write_status(CNTR_STATUS_MERGING,
				csb->path.buf, cntr)) goto end;
			switch(manio_copy_entry(
				csb, csb, &blk, chmanio, newmanio))
			{
				case -1: goto end;
				case 1: manio_close(&chmanio);
			}
		}
		else if(pcmp<0)
		{
			if(write_status(CNTR_STATUS_MERGING,
				usb->path.buf, cntr)) goto end;
			switch(manio_copy_entry(
				usb, usb, &blk, unmanio, newmanio))
			{
				case -1: goto end;
				case 1: manio_close(&unmanio);
			}
		}
		else
		{
			if(write_status(CNTR_STATUS_MERGING,
				csb->path.buf, cntr)) goto end;
			switch(manio_copy_entry(
				csb, csb, &blk, chmanio, newmanio))
			{
				case -1: goto end;
				case 1: manio_close(&chmanio);
			}
		}
	}

	// Flush to disk.
	if(manio_close(&newmanio))
	{
		logp("error gzclosing %s in backup_phase3_server\n",
			manifesttmp);
		goto end;
	}

	// Rename race condition should be of no consequence here, as the
	// manifest should just get recreated automatically.
	if(do_rename(manifesttmp, sdirs->manifest))
		goto end;
	else
	{
		recursive_delete(sdirs->changed);
		recursive_delete(sdirs->unchanged);
	}

	logp("End phase3 (merge manifests)\n");
	ret=0;
end:
	manio_close(&newmanio);
	manio_close(&chmanio);
	manio_close(&unmanio);
	sbuf_free(&csb);
	sbuf_free(&usb);
	blk_free(&blk);
	free_w(&manifesttmp);
	return ret;
}
Esempio n. 14
0
// This is basically backup_phase3_server() from protocol1. It used to merge the
// unchanged and changed data into a single file. Now it splits the manifests
// into several files.
int backup_phase3_server_protocol2(struct sdirs *sdirs, struct conf **confs)
{
	int ret=1;
	int pcmp=0;
	char *hooksdir=NULL;
	char *dindexdir=NULL;
	char *manifesttmp=NULL;
	struct sbuf *usb=NULL;
	struct sbuf *csb=NULL;
	struct blk *blk=NULL;
	int finished_ch=0;
	int finished_un=0;
	struct manio *newmanio=NULL;
	struct manio *chmanio=NULL;
	struct manio *unmanio=NULL;
	uint64_t fcount=0;

	logp("Start phase3\n");

	if(!(manifesttmp=get_tmp_filename(sdirs->rmanifest))
	  || !(newmanio=manio_alloc())
	  || !(chmanio=manio_alloc())
	  || !(unmanio=manio_alloc())
	  || !(hooksdir=prepend_s(manifesttmp, "hooks"))
	  || !(dindexdir=prepend_s(manifesttmp, "dindex"))
	  || manio_init_write(newmanio, manifesttmp)
	  || manio_init_write_hooks(newmanio,
		get_string(confs[OPT_DIRECTORY]), hooksdir, sdirs->rmanifest)
	  || manio_init_write_dindex(newmanio, dindexdir)
	  || manio_init_read(chmanio, sdirs->changed)
	  || manio_init_read(unmanio, sdirs->unchanged)
	  || !(usb=sbuf_alloc(confs))
	  || !(csb=sbuf_alloc(confs)))
		goto end;

	while(!finished_ch || !finished_un)
	{
		if(!blk && !(blk=blk_alloc())) goto end;

		if(!finished_un
		  && usb
		  && !usb->path.buf)
		{
			switch(manio_sbuf_fill(unmanio, NULL /* no async */,
				usb, NULL, NULL, confs))
			{
				case -1: goto end;
				case 1: finished_un++;
			}
		}

		if(!finished_ch
		  && csb
		  && !csb->path.buf)
		{
			switch(manio_sbuf_fill(chmanio, NULL /* no async */,
				csb, NULL, NULL, confs))
			{
				case -1: goto end;
				case 1: finished_ch++;
			}
		}

		if((usb && usb->path.buf) && (!csb || !csb->path.buf))
		{
			switch(manio_copy_entry(NULL /* no async */,
				&usb, usb,
				&blk, unmanio, newmanio, confs))
			{
				case -1: goto end;
				case 1: finished_un++;
			}
		}
		else if((!usb || !usb->path.buf) && (csb && csb->path.buf))
		{
			switch(manio_copy_entry(NULL /* no async */,
				&csb, csb, &blk, chmanio, newmanio, confs))
			{
				case -1: goto end;
				case 1: finished_ch++;
			}
		}
		else if((!usb || !usb->path.buf) && (!csb || !(csb->path.buf)))
		{
			continue;
		}
		else if(!(pcmp=sbuf_pathcmp(usb, csb)))
		{
			// They were the same - write one.
			switch(manio_copy_entry(NULL /* no async */,
				&csb, csb, &blk, chmanio, newmanio, confs))
			{
				case -1: goto end;
				case 1: finished_ch++;
			}
		}
		else if(pcmp<0)
		{
			switch(manio_copy_entry(NULL /* no async */,
				&usb, usb, &blk, unmanio, newmanio, confs))
			{
				case -1: goto end;
				case 1: finished_un++;
			}
		}
		else
		{
			switch(manio_copy_entry(NULL /* no async */,
				&csb, csb, &blk, chmanio, newmanio, confs))
			{
				case -1: goto end;
				case 1: finished_ch++;
			}
		}
	}

	fcount=newmanio->fcount;

	// Flush to disk and set up for reading.
	if(manio_free(&newmanio)
	  || !(newmanio=manio_alloc())
	  || manio_init_read(newmanio, sdirs->rmanifest))
		goto end;

	// Rename race condition should be of no consequence here, as the
	// manifest should just get recreated automatically.
	if(do_rename(manifesttmp, sdirs->rmanifest))
		goto end;
	else
	{
		recursive_delete(sdirs->changed, NULL, 1);
		recursive_delete(sdirs->unchanged, NULL, 1);
	}

	if(sparse_generation(newmanio, fcount, sdirs, confs))
		goto end;

	ret=0;

	logp("End phase3\n");
end:
	manio_free(&newmanio);
	manio_free(&chmanio);
	manio_free(&unmanio);
	sbuf_free(&csb);
	sbuf_free(&usb);
	blk_free(&blk);
	free_w(&hooksdir);
	free_w(&dindexdir);
	free_w(&manifesttmp);
	return ret;
}
Esempio n. 15
0
/**
 * Creates a veh_interact window based on the given parameters.
 * @param v The vehicle the player is interacting with.
 * @param x The x-coordinate of the square the player is 'e'xamining.
 * @param y The y-coordinate of the square the player is 'e'xamining.
 */
void veh_interact::exec (game *gm, vehicle *v, int x, int y)
{
    g = gm;
    veh = v;
    //        x1      x2
    // y1 ----+------+--
    //        |      |
    // y2 ----+------+
    //               |
    //               |
    winw1 = 12;
    winw2 = 35;
    winh1 = 3;
    winh2 = 12;
    winw12 = winw1 + winw2 + 1;
    winw3 = FULL_SCREEN_WIDTH - winw1 - winw2 - 2;
    winh3 = FULL_SCREEN_HEIGHT - winh1 - winh2 - 2;
    winh23 = winh2 + winh3 + 1;
    winx1 = winw1;
    winx2 = winw1 + winw2 + 1;
    winy1 = winh1;
    winy2 = winh1 + winh2 + 1;

    // changed FALSE value to 1, to keep w_border from starting at a negative x,y
    const int iOffsetX = (TERMX > FULL_SCREEN_WIDTH) ? (TERMX-FULL_SCREEN_WIDTH)/2 : 1;
    const int iOffsetY = (TERMY > FULL_SCREEN_HEIGHT) ? (TERMY-FULL_SCREEN_HEIGHT)/2 : 1;

    page_size = winh23;

    //               h   w    y     x
    WINDOW *w_border= newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH,  -1 + iOffsetY,    -1 + iOffsetX);
    w_grid  = newwin(FULL_SCREEN_HEIGHT -2, FULL_SCREEN_WIDTH-2,  iOffsetY,    iOffsetX);
    w_mode  = newwin(1,  FULL_SCREEN_WIDTH-2, iOffsetY,    iOffsetX);
    w_msg   = newwin(winh1 - 1, FULL_SCREEN_WIDTH-2, 1 + iOffsetY,    iOffsetX);
    w_disp  = newwin(winh2-1, winw1,  winy1 + 1 + iOffsetY, iOffsetX);
    w_parts = newwin(winh2-1, winw2,  winy1 + 1 + iOffsetY, winx1 + 1 + iOffsetX);
    w_stats = newwin(winh3-1, winw12, winy2 + iOffsetY, iOffsetX);
    w_list  = newwin(winh23, winw3, winy1 + 1 + iOffsetY, winx2 + 1 + iOffsetX);

    wborder(w_border, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX,
                      LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX );

    mvwputch(w_border, 16, 0, c_ltgray, LINE_XXXO); // |-
    mvwputch(w_border, 4, 0, c_ltgray, LINE_XXXO); // |-
    mvwputch(w_border, 4, FULL_SCREEN_WIDTH-1, c_ltgray, LINE_XOXX); // -|
    mvwputch(w_border, 24, 49, c_ltgray, LINE_XXOX);

    wrefresh(w_border);

    for (int i = 0; i < FULL_SCREEN_HEIGHT; i++)
    {
        mvwputch(w_grid, i, winx2, c_ltgray, i == winy1 || i == winy2-1? LINE_XOXX : LINE_XOXO);
        if (i >= winy1 && i < winy2) {
            mvwputch(w_grid, i, winx1, c_ltgray, LINE_XOXO);
        }
    }
    for (int i = 0; i < FULL_SCREEN_WIDTH; i++)
    {
        mvwputch(w_grid, winy1, i, c_ltgray,
                 i == winx1? LINE_OXXX : (i == winx2? LINE_OXXX : LINE_OXOX));
        if (i < winx2) {
            mvwputch(w_grid, winy2-1, i, c_ltgray, i == winx1? LINE_XXOX : LINE_OXOX);
        }
    }
    wrefresh(w_grid);

    crafting_inv = gm->crafting_inventory(&gm->u);

    int charges = static_cast<it_tool *>(g->itypes["welder"])->charges_per_use;
    int charges_crude = static_cast<it_tool *>(g->itypes["welder_crude"])->charges_per_use;
    has_wrench = crafting_inv.has_amount("wrench", 1) ||
        crafting_inv.has_amount("toolset", 1);
    has_hacksaw = crafting_inv.has_amount("hacksaw", 1) ||
        crafting_inv.has_amount("toolset", 1);
    has_welder = (crafting_inv.has_amount("welder", 1) &&
                  crafting_inv.has_charges("welder", charges)) ||
                  (crafting_inv.has_amount("welder_crude", 1) &&
                  crafting_inv.has_charges("welder_crude", charges_crude)) ||
                (crafting_inv.has_amount("toolset", 1) &&
                 crafting_inv.has_charges("toolset", charges/20));
    has_jack = crafting_inv.has_amount("jack", 1);
    has_siphon = crafting_inv.has_amount("hose", 1);

    has_wheel = crafting_inv.has_amount( "wheel", 1 ) ||
                crafting_inv.has_amount( "wheel_wide", 1 ) ||
                crafting_inv.has_amount( "wheel_bicycle", 1 ) ||
                crafting_inv.has_amount( "wheel_motorbike", 1 ) ||
                crafting_inv.has_amount( "wheel_small", 1 );

    display_stats ();
    display_veh   ();
    move_cursor (0, 0);
    bool finish = false;
    while (!finish)
    {
        char ch = input(); // See keypress.h
        int dx, dy;
        get_direction (dx, dy, ch);
        if (ch == KEY_ESCAPE || ch == 'q' )
        {
            finish = true;
        } 
        else
        {
            if (dx != -2 && (dx || dy) &&
                cursor_x + dx >= -6 && cursor_x + dx < 6 &&
                cursor_y + dy >= -6 && cursor_y + dy < 6)
            {
                move_cursor(dx, dy);
            }
            else
            {
                int mval = cant_do(ch);
                display_mode (ch);
                switch (ch)
                {
                    case 'i': do_install(mval); break;
                    case 'r': do_repair(mval);  break;
                    case 'f': do_refill(mval);  break;
                    case 'o': do_remove(mval);  break;
                    case 'e': do_rename(mval);  break;
                    case 's': do_siphon(mval);  break;
                    case 'c': do_tirechange(mval); break;
                    case 'd': do_drain(mval);  break;
                }
                if (sel_cmd != ' ')
                {
                    finish = true;
                }
                display_mode (' ');
            }
        }
    }
    werase(w_grid);
    werase(w_mode);
    werase(w_msg);
    werase(w_disp);
    werase(w_parts);
    werase(w_stats);
    werase(w_list);
    delwin(w_grid);
    delwin(w_mode);
    delwin(w_msg);
    delwin(w_disp);
    delwin(w_parts);
    delwin(w_stats);
    delwin(w_list);
    erase();
}
Esempio n. 16
0
/*
 * Finish off the rename, by either over writing the last destination or
 * unlinking the last destination to the left of us
 */
static int __rename_all_clobber(struct inode *old_dir,
				struct dentry *old_dentry,
				struct inode *new_dir,
				struct dentry *new_dentry,
				struct rename_info *info)
{
	int err = 0;

	print_entry_location();

	if (dtohd_index(old_dentry, info->new_bstart)) {
		/* rename the last source, knowing we're overwriting something */
		DPUT(info->wh_old);
		info->bwh_old = info->new_bstart;
		err =
		    do_rename(old_dir, old_dentry, new_dir, new_dentry,
			      info->new_bstart, &info->wh_old);
		if (IS_COPYUP_ERR(err)) {
			if (info->isdir) {
				err = -EXDEV;
				goto out;
			}
			if (info->rename_ok > info->new_bstart) {
				if ((info->do_copyup == -1)
				    || (info->new_bstart - 1 < info->do_copyup))
					info->do_copyup = info->new_bstart - 1;
			}
			if ((info->do_whiteout == -1)
			    || (info->new_bstart - 1 < info->do_whiteout)) {
				info->do_whiteout = info->new_bstart - 1;
			}
			err = 0;	// reset error
		}
	} else if (info->new_bstart < info->old_bstart) {
		/* the newly renamed file would get hidden, let's unlink the
		 * file to the left of it */
		struct dentry *unlink_dentry;
		struct dentry *unlink_dir_dentry;

		unlink_dentry = dtohd_index(new_dentry, info->new_bstart);

		unlink_dir_dentry = lock_parent(unlink_dentry);
		if (!(err = is_robranch_super(old_dir->i_sb, info->new_bstart)))
			err = vfs_unlink(unlink_dir_dentry->d_inode,
					 unlink_dentry);

		fist_copy_attr_times(new_dentry->d_parent->d_inode,
				     unlink_dir_dentry->d_inode);
		new_dentry->d_parent->d_inode->i_nlink =
		    get_nlinks(new_dentry->d_parent->d_inode);

		unlock_dir(unlink_dir_dentry);

		if (IS_COPYUP_ERR(err)) {
			if (info->isdir) {
				err = -EXDEV;
				goto out;
			}
			if ((info->do_copyup == -1)
			    || (info->new_bstart - 1 < info->do_copyup))
				info->do_copyup = info->new_bstart - 1;

			err = 0;	// reset error
		}
	}

      out:
	print_exit_status(err);
	return err;
}
Esempio n. 17
0
int backup_phase4_server_protocol2(struct sdirs *sdirs, struct conf **confs)
{
	int ret=-1;
	uint64_t i=0;
	uint64_t pass=0;
	char *sparse=NULL;
	char *global_sparse=NULL;
	char *h1dir=NULL;
	char *h2dir=NULL;
	char *hooksdir=NULL;
	char *srca=NULL;
	char *srcb=NULL;
	char *dst=NULL;
	char compa[32]="";
	char compb[32]="";
	char compd[32]="";
	struct manio *newmanio=NULL;
	char *logpath=NULL;
	char *fmanifest=NULL; // FIX THIS: should be part of sdirs.

	if(!(logpath=prepend_s(sdirs->finishing, "log")))
		goto end;
	if(set_logfp(logpath, confs))
		goto end;

	logp("Begin phase4 (sparse generation)\n");

	if(!(newmanio=manio_alloc())
	  || !(fmanifest=prepend_s(sdirs->finishing, "manifest"))
	  || manio_init_read(newmanio, fmanifest)
	  || manio_read_fcount(newmanio)
	  || !(hooksdir=prepend_s(fmanifest, "hooks"))
	  || !(h1dir=prepend_s(fmanifest, "h1"))
	  || !(h2dir=prepend_s(fmanifest, "h2")))
		goto end;

	while(1)
	{
		char *srcdir=NULL;
		char *dstdir=NULL;
		if(!pass)
		{
			srcdir=hooksdir;
			dstdir=h1dir;
		}
		else if(pass%2)
		{
			srcdir=h1dir;
			dstdir=h2dir;
		}
		else
		{
			srcdir=h2dir;
			dstdir=h1dir;
		}
		pass++;
		for(i=0; i<newmanio->offset.fcount; i+=2)
		{
			free_w(&srca);
			free_w(&srcb);
			free_w(&dst);
			snprintf(compa, sizeof(compa), "%08"PRIX64, i);
			snprintf(compb, sizeof(compb), "%08"PRIX64, i+1);
			snprintf(compd, sizeof(compd), "%08"PRIX64, i/2);
			if(!(srca=prepend_s(srcdir, compa))
			  || !(dst=prepend_s(dstdir, compd)))
				goto end;
			if(i+1<newmanio->offset.fcount
			  && !(srcb=prepend_s(srcdir, compb)))
				goto end;
			if(merge_sparse_indexes(srca, srcb, dst, confs))
				goto end;
		}
		if((newmanio->offset.fcount=i/2)<2) break;
	}

	if(!(sparse=prepend_s(fmanifest, "sparse"))
	  || !(global_sparse=prepend_s(sdirs->data, "sparse")))
		goto end;

	// FIX THIS: nasty race condition here needs to be automatically
	// recoverable.
	if(do_rename(dst, sparse)) goto end;

	if(merge_into_global_sparse(sparse, global_sparse, confs)) goto end;

	logp("End phase4 (sparse generation)\n");

	ret=0;
end:
	manio_free(&newmanio);
	free_w(&sparse);
	free_w(&global_sparse);
	free_w(&srca);
	free_w(&srcb);
	recursive_delete(h1dir, NULL, 1);
	recursive_delete(h2dir, NULL, 1);
	free_w(&h1dir);
	free_w(&h2dir);
	free_w(&logpath);
	free_w(&fmanifest);
	return ret;
}
Esempio n. 18
0
/* Need to make all the stuff that this does atomic so that existing backups
   never get broken, even if somebody turns the power off on the server. */ 
static int atomic_data_jiggle(struct sdirs *sdirs, struct fdirs *fdirs,
	int hardlinked_current, struct conf *cconf, unsigned long bno)
{
	int ars=0;
	int ret=-1;
	char *datapth=NULL;
	char *tmpman=NULL;
	struct stat statp;

	char *deltabdir=NULL;
	char *deltafdir=NULL;
	char *sigpath=NULL;
	gzFile zp=NULL;
	struct sbuf *sb=NULL;

	FILE *delfp=NULL;

	logp("Doing the atomic data jiggle...\n");

	if(!(tmpman=get_tmp_filename(fdirs->manifest)))
		goto end;
	if(lstat(fdirs->manifest, &statp))
	{
		// Manifest does not exist - maybe the server was killed before
		// it could be renamed.
		logp("%s did not exist - trying %s\n", fdirs->manifest, tmpman);
		// Rename race condition is of no consequence, because manifest
		// already does not exist.
		do_rename(tmpman, fdirs->manifest);
	}
	if(!(zp=gzopen_file(fdirs->manifest, "rb")))
		goto end;

	if(!(deltabdir=prepend_s(fdirs->currentdup, "deltas.reverse"))
	  || !(deltafdir=prepend_s(sdirs->finishing, "deltas.forward"))
	  || !(sigpath=prepend_s(fdirs->currentdup, "sig.tmp"))
	  || !(sb=sbuf_alloc(cconf)))
	{
		log_out_of_memory(__func__);
		goto end;
	}

	mkdir(fdirs->datadir, 0777);

	while(!(ars=sbufl_fill(sb, NULL, NULL, zp, cconf->cntr)))
	{
		if(sb->burp1->datapth.buf)
		{
			if(write_status(STATUS_SHUFFLING,
				sb->burp1->datapth.buf, cconf)) goto end;

			if((ret=jiggle(sdirs, fdirs, sb, hardlinked_current,
				deltabdir, deltafdir,
				sigpath, &delfp, cconf))) goto end;
		}
		sbuf_free_content(sb);
	}
	if(ars<0) goto end;

	if(close_fp(&delfp))
	{
		logp("error closing %s in atomic_data_jiggle\n",
			fdirs->deletionsfile);
		goto end;
	}

	if(maybe_delete_files_from_manifest(tmpman, fdirs, cconf))
		goto end;

	// Remove the temporary data directory, we have probably removed
	// useful files from it.
	sync(); // try to help CIFS
	recursive_delete(deltafdir, NULL, 0 /* do not del files */);

end:
	gzclose_fp(&zp);
	close_fp(&delfp);
	sbuf_free(&sb);
	free_w(&deltabdir);
	free_w(&deltafdir);
	free_w(&sigpath);
	free_w(&datapth);
	free_w(&tmpman);
	return ret;
}
Esempio n. 19
0
int backup_phase4_server_burp1(struct sdirs *sdirs, struct conf *cconf)
{
	int ret=-1;
	struct stat statp;
	ssize_t len=0;
	char realcurrent[256]="";
	unsigned long bno=0;
	int hardlinked_current=0;
	char tstmp[64]="";
	int previous_backup=0;
	struct fdirs *fdirs=NULL;

	if((len=readlink(sdirs->current, realcurrent, sizeof(realcurrent)-1))<0)
		len=0;
	realcurrent[len]='\0';

	if(!(fdirs=fdirs_alloc())
	  || fdirs_init(fdirs, sdirs, realcurrent))
		goto end;

	if(set_logfp(fdirs->logpath, cconf))
		goto end;

	logp("Begin phase4 (shuffle files)\n");

	if(write_status(STATUS_SHUFFLING, NULL, cconf))
		goto end;

	if(!lstat(sdirs->current, &statp)) // Had a previous backup.
	{
		previous_backup++;

		if(lstat(fdirs->hlinkedcurrent, &statp))
		{
			hardlinked_current=0;
			logp("Previous backup is not a hardlinked_archive\n");
			logp(" will generate reverse deltas\n");
		}
		else
		{
			hardlinked_current=1;
			logp("Previous backup is a hardlinked_archive\n");
			logp(" will not generate reverse deltas\n");
		}

		// If current was not a hardlinked_archive, need to duplicate
		// it.
		if(!hardlinked_current && lstat(fdirs->currentdup, &statp))
		{
			// Have not duplicated the current backup yet.
			if(!lstat(fdirs->currentduptmp, &statp))
			{
				logp("Removing previous directory: %s\n",
					fdirs->currentduptmp);
				if(recursive_delete(fdirs->currentduptmp,
					NULL, 1 /* del files */))
				{
					logp("Could not delete %s\n",
						fdirs->currentduptmp);
					goto end;
				}
			}
			logp("Duplicating current backup.\n");
			if(recursive_hardlink(sdirs->current,
				fdirs->currentduptmp, cconf)
			// The rename race condition is of no consequence here
			// because currentdup does not exist.
			  || do_rename(fdirs->currentduptmp, fdirs->currentdup))
				goto end;
		}
	}

	if(timestamp_read(fdirs->timestamp, tstmp, sizeof(tstmp)))
	{
		logp("could not read timestamp file: %s\n",
			fdirs->timestamp);
		goto end;
	}
	// Get the backup number.
	bno=strtoul(tstmp, NULL, 10);

	// Determine whether the new backup should be a hardlinked
	// archive or not, from the conf and the backup number...
	if(need_hardlinked_archive(cconf, bno))
	{
		// Create a file to indicate that the previous backup
		// does not have others depending on it.
		FILE *hfp=NULL;
		if(!(hfp=open_file(fdirs->hlinked, "wb"))) goto end;

		// Stick the next backup timestamp in it. It might
		// be useful one day when wondering when the next
		// backup, now deleted, was made.
		fprintf(hfp, "%s\n", tstmp);
		if(close_fp(&hfp))
		{
			logp("error closing hardlinked indication\n");
			goto end;
		}
	}
	else
		unlink(fdirs->hlinked);

	if(atomic_data_jiggle(sdirs, fdirs, hardlinked_current, cconf, bno))
	{
		logp("could not finish up backup.\n");
		goto end;
	}

	if(write_status(STATUS_SHUFFLING, "deleting temporary files", cconf))
		goto end;

	// Remove the temporary data directory, we have now removed
	// everything useful from it.
	recursive_delete(fdirs->datadirtmp, NULL, 1 /* del files */);

	// Clean up the currentdata directory - this is now the 'old'
	// currentdata directory. Any files that were deleted from
	// the client will be left in there, so call recursive_delete
	// with the option that makes it not delete files.
	// This will have the effect of getting rid of unnecessary
	// directories.
	sync(); // try to help CIFS
	recursive_delete(fdirs->currentdupdata, NULL, 0 /* do not del files */);

	// Rename the old current to something that we know to delete.
	if(previous_backup && !hardlinked_current)
	{
		if(deleteme_move(sdirs->client,
			fdirs->fullrealcurrent, realcurrent, cconf)
		// I have tested that potential race conditions on the
		// rename() are automatically recoverable here.
		  || do_rename(fdirs->currentdup, fdirs->fullrealcurrent))
			goto end;
	}

	if(deleteme_maybe_delete(cconf, sdirs->client))
		goto end;

	cntr_stats_to_file(cconf->cntr, sdirs->finishing, ACTION_BACKUP);

	logp("End phase4 (shuffle files)\n");

	ret=0;
end:
	fdirs_free(fdirs);
	return ret;
}
Esempio n. 20
0
/*
 * The function is nasty, nasty, nasty, but so is rename. :(
 */
static int unionfs_rename_all(struct inode *old_dir, struct dentry *old_dentry,
			      struct inode *new_dir, struct dentry *new_dentry)
{
	struct dentry *parent_dentry = NULL;
	int err = 0;
	int eio;

	/* These variables control error handling. */
	fd_set success_mask;
	char *name = NULL;

	/* unfortunately, we have to resort to this, because dbstart/dbend would
	   return different things in different place of the rename code */
	struct rename_info info;

	info.rename_ok = FD_SETSIZE;	/* The last rename that is ok. */
	info.do_copyup = -1;	/* Where we should start copyup. */
	info.do_whiteout = -1;	/* Where we should start whiteouts of the source. */
	info.wh_old = NULL;
	info.bwh_old = -1;

	print_entry_location();

	parent_dentry = old_dentry->d_parent;
	name = KMALLOC(old_dentry->d_name.len + 1, GFP_KERNEL);
	if (!name) {
		err = -ENOMEM;
		goto out;
	}
	strncpy(name, old_dentry->d_name.name, old_dentry->d_name.len + 1);

	info.new_bstart = dbstart(new_dentry);
	info.new_bend = dbend(new_dentry);

	info.old_bstart = dbstart(old_dentry);
	info.old_bend = dbend(old_dentry);

	BUG_ON(info.new_bstart < 0);
	BUG_ON(info.old_bstart < 0);

	/* The failure mask only can deal with FD_SETSIZE entries. */
	BUG_ON(info.old_bend > FD_SETSIZE);
	BUG_ON(info.new_bend > FD_SETSIZE);
	FD_ZERO(&success_mask);

	/* Life is simpler if the dentry doesn't exist. */
	info.clobber =
	    (dtohd_index(new_dentry, info.new_bstart)->d_inode) ? 1 : 0;
	info.isdir = S_ISDIR(old_dentry->d_inode->i_mode);

	/* rename everything we can */
	err =
	    __rename_all(old_dir, old_dentry, new_dir, new_dentry,
			 &success_mask, &info);
	if (err)
		goto revert;

	/* unlink destinations even further left */
	err =
	    __rename_all_unlink(old_dir, old_dentry, new_dir, new_dentry,
				&info);
	if (err)
		goto revert;

	if (info.clobber) {
		/* Now we need to handle the leftmost of the destination. */
		err =
		    __rename_all_clobber(old_dir, old_dentry, new_dir,
					 new_dentry, &info);
		if (err)
			goto revert;
	}

	/* Copy up if necessary */
	if (info.do_copyup != -1) {
		int bindex;

		for (bindex = info.do_copyup; bindex >= 0; bindex--) {
			err =
			    copyup_dentry(old_dentry->d_parent->d_inode,
					  old_dentry, info.old_bstart, bindex,
					  NULL, old_dentry->d_inode->i_size);
			if (!err) {
				DPUT(info.wh_old);
				info.bwh_old = bindex;
				err =
				    do_rename(old_dir, old_dentry, new_dir,
					      new_dentry, bindex, &info.wh_old);
				break;
			}
		}
	}

	/* Create a whiteout for the source. */
	if (info.do_whiteout != -1) {
		struct dentry *hidden_parent;
		BUG_ON(info.do_whiteout < 0
		       || !info.wh_old || IS_ERR(info.wh_old)
		       || info.wh_old->d_inode || info.bwh_old < 0);
		hidden_parent = lock_parent(info.wh_old);
		err = vfs_create(hidden_parent->d_inode, info.wh_old, S_IRUGO,
				 NULL);
		unlock_dir(hidden_parent);
		if (!err)
			set_dbopaque(old_dentry, info.bwh_old);
		else {
			/* We can't fix anything now, so we -EIO. */
			printk(KERN_WARNING "We can't create a whiteout for the"
			       "source in rename!\n");
			err = -EIO;
			goto out;
		}
	}

	/* We are at the point where reverting doesn't happen. */
	goto out;

      revert:
	/* something bad happened, try to revert */
	eio =
	    __rename_all_revert(old_dir, old_dentry, new_dir, new_dentry,
				&success_mask, &info);
	if (eio)
		err = eio;

      out:
	DPUT(info.wh_old);
	KFREE(name);
	print_exit_status(err);
	return err;
}
Esempio n. 21
0
static int maybe_delete_files_from_manifest(const char *manifesttmp,
	struct fdirs *fdirs, struct conf *cconf)
{
	int ars=0;
	int ret=-1;
	int pcmp=0;
	FILE *dfp=NULL;
	gzFile nmzp=NULL;
	gzFile omzp=NULL;
	struct sbuf *db=NULL;
	struct sbuf *mb=NULL;
	struct stat statp;

	if(lstat(fdirs->deletionsfile, &statp)) // No deletions, no problem.
		return 0;
	logp("Performing deletions on manifest\n");

	if(!(manifesttmp=get_tmp_filename(fdirs->manifest)))
		goto end;

        if(!(dfp=open_file(fdirs->deletionsfile, "rb"))
	  || !(omzp=gzopen_file(fdirs->manifest, "rb"))
	  || !(nmzp=gzopen_file(manifesttmp, comp_level(cconf)))
	  || !(db=sbuf_alloc(cconf))
	  || !(mb=sbuf_alloc(cconf)))
		goto end;

	while(omzp || dfp)
	{
		if(dfp && !db->path.buf
		  && (ars=sbufl_fill(db, NULL, dfp, NULL, cconf->cntr)))
		{
			if(ars<0) goto end;
			// ars==1 means it ended ok.
			close_fp(&dfp);
		}
		if(omzp && !mb->path.buf
		  && (ars=sbufl_fill(mb, NULL, NULL, omzp, cconf->cntr)))
		{
			if(ars<0) goto end;
			// ars==1 means it ended ok.
			gzclose_fp(&omzp);
		}

		if(mb->path.buf && !db->path.buf)
		{
			if(sbufl_to_manifest(mb, NULL, nmzp)) goto end;
			sbuf_free_content(mb);
		}
		else if(!mb->path.buf && db->path.buf)
		{
			sbuf_free_content(db);
		}
		else if(!mb->path.buf && !db->path.buf) 
		{
			continue;
		}
		else if(!(pcmp=sbuf_pathcmp(mb, db)))
		{
			// They were the same - do not write.
			sbuf_free_content(mb);
			sbuf_free_content(db);
		}
		else if(pcmp<0)
		{
			// Behind in manifest. Write.
			if(sbufl_to_manifest(mb, NULL, nmzp)) goto end;
			sbuf_free_content(mb);
		}
		else
		{
			// Behind in deletions file. Do not write.
			sbuf_free_content(db);
		}
	}

	ret=0;
end:
	if(gzclose_fp(&nmzp))
	{
		logp("error closing %s in %s\n", manifesttmp, __func__);
		ret=-1;
	}
	
	close_fp(&dfp);
	gzclose_fp(&omzp);
	sbuf_free(&db);
	sbuf_free(&mb);
	if(!ret)
	{
		unlink(fdirs->deletionsfile);
		// The rename race condition is not a problem here, as long
		// as manifesttmp is the same path as that generated in the
		// atomic data jiggle.
		if(do_rename(manifesttmp, fdirs->manifest))
			return -1;
	}
	if(manifesttmp) unlink(manifesttmp);
	return ret;
}
Esempio n. 22
0
void *extra_self_tests(int arg1, void *arg2)
{
        /* creating /test1/test2/ directories */
   dbg(DBG_ERROR | DBG_VFS,"TEST: Creating directories\n");        
                do_mkdir("dir");
                do_mkdir("dir/dir1");
                do_mkdir("dir/dir2");
                do_mkdir("dir/dir3");             
                do_mkdir("dir/dir4");  
   dbg(DBG_ERROR | DBG_VFS,"TEST: Directories are created\n");
        int fd;
        char *file2buf="File 2 write only test case";
        char *file1buf="Testing file_1 for write operation";
        char readbuf[150];

   dbg(DBG_ERROR | DBG_VFS,"TEST: Change directory to dir/dir1\n");
        do_chdir("dir/dir1");

        /* file1.txt creation with O_CREAT|O_WRONLY  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Create file1.txt with O_CREAT|O_WRONLY flag in directory dir/dir1\n");
        fd = do_open("file1.txt", O_CREAT|O_WRONLY);
        do_write(fd, file1buf, strlen(file1buf));
        do_close(fd);
        
        /* file2.txt creation with O_CREAT|O_RDONLY  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Change directory to dir/dir2\n");
        do_chdir("/dir/dir2");
        
   dbg(DBG_ERROR | DBG_VFS,"TEST: Create file2.txt with O_CREAT | O_RDONLY flag  in directory dir/dir2\n");
        fd = do_open("file2.txt", O_CREAT | O_RDONLY);
        do_close(fd);
        
         /* Write into file2.txt using O_WRONLY flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Write into file2.txt with O_WRONLY flag in directory dir/dir2\n");  
        fd = do_open("file2.txt", O_WRONLY);
        do_write(fd, file2buf, strlen(file2buf));
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: written chars: \"%s\" in file2.txt\n",file2buf);
   
        char *appendbuf=" Appending for O_WRONLY|O_APPEND mode";
      /* Append into file2.txt using  O_WRONLY|O_APPEND  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Append into file2.txt with O_WRONLY|O_APPEND flag in directory dir/dir2\n");  
        fd = do_open("file2.txt", O_WRONLY|O_APPEND);
        do_write(fd, appendbuf, strlen(appendbuf));
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: Appending chars: \"%s\" in file2.txt\n",appendbuf);
        fd = do_open("file2.txt", O_RDONLY);
        memset(readbuf,0,sizeof(char)*150);
        do_read(fd,readbuf,strlen(file2buf)+strlen(appendbuf));
   dbg(DBG_ERROR | DBG_VFS,"TEST: After Appending text in file2.txt is: \"%s\" \n",readbuf);

        char *append2buf=" Appending for O_RDWR|O_APPEND mode in file2";
      /* Append into file2.txt using  O_RDWR|O_APPEND  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Append into file2.txt with O_RDWR|O_APPEND flag in directory dir/dir2\n");  
        fd = do_open("file2.txt", O_RDWR|O_APPEND);
        do_write(fd, append2buf, strlen(append2buf));
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: Appending chars: \"%s\" in file2.txt\n",append2buf);
        fd = do_open("file2.txt", O_RDONLY);
        memset(readbuf,0,sizeof(char)*150);
        do_read(fd,readbuf,strlen(file2buf)+strlen(append2buf)+strlen(appendbuf));
   dbg(DBG_ERROR | DBG_VFS,"TEST: After Appending text in file2.txt is: \"%s\" \n",readbuf);

   dbg(DBG_ERROR | DBG_VFS,"TEST:Linking Source directory => /dir/dir2, Destination directory => /dir/linkofdir2 \n");
        do_chdir("/");
        do_link("dir/dir2","dir/linkofdir2");

   dbg(DBG_ERROR | DBG_VFS,"TEST:Linking Source file => /dir/dir1/file1.txt, to the Destination => /dir/linkoffile1 \n");
        do_link("dir/dir1/file1.txt","dir/linkoffile1");
        
   dbg(DBG_ERROR | DBG_VFS,"TEST: Renaming directory from dir/dir3 to dir/renamed \n");
        do_rename("dir/dir3","dir/renameddir3");

   dbg(DBG_ERROR | DBG_VFS,"TEST: Renaming file from dir/dir1/file1.txt to dir/dir1/renamedfile1.txt \n");
        do_rename("dir/dir1/file1.txt","dir/dir1/renamedfile1.txt");

   dbg(DBG_ERROR | DBG_VFS,"TEST: Removing directory dir/dir4 \n");
        do_rmdir("dir/dir4");

   dbg(DBG_ERROR | DBG_VFS,"TEST: reading 18 chars from file: /dir/linkoffile2 which is hard link of /dir/dir2/file2.txt \n");
        fd = do_open("dir/linkoffile2", O_RDONLY);
        memset(readbuf,0,sizeof(char)*150);
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: read 18 chars: \"%s\" from file: /dir/linkoffile1\n",readbuf);
   
   dbg(DBG_ERROR | DBG_VFS,"TEST: reading file using lseek function on  /dir/linkoffile2 which is hard link of /dir/dir2/file2.txt \n");
        memset(readbuf,0,sizeof(char)*150);
        fd = do_open("dir/linkoffile2", O_RDONLY);
        do_lseek(fd,-19,2);
        do_read(fd,readbuf,19);
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: read chars: \"%s\" using lseek from file: /dir/linkoffile1\n",readbuf);
   
   dbg(DBG_ERROR | DBG_VFS,"TEST: creating a duplicate file descriptor of file: /dir/dir2/file2.txt using do_dup()\n");
        fd = do_open("/dir/dir2/file2.txt", O_RDONLY);
    int fd2= do_dup(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: duplicate file descriptor is :\"%d\" of file: /dir/dir2/file2.txt \n",fd2);
             do_close(fd);        do_close(fd2);
                     
   dbg(DBG_ERROR | DBG_VFS,"TEST: creating a duplicate file descriptor of file: /dir/dir2/file2.txt using do_dup2()\n");    
        fd = do_open("/dir/dir2/file2.txt", O_RDONLY);
        fd2= do_dup2(fd,20);
   dbg(DBG_ERROR | DBG_VFS,"TEST: custom file descriptor is :\"%d\" of file: /dir/dir2/file2.txt \n",fd2);
                do_close(fd);        do_close(fd2);

        /*  Testing stat
        struct *statbuf;
   dbg(DBG_ERROR | DBG_VFS,"TEST: Testing the stat system call for directory dir\n");
        do_stat("dir",statbuf);
   dbg(DBG_ERROR | DBG_VFS,"TEST: Output of stat for directory dir is :\"%s\" \n",statbuf);*/

        shellTest(); 

     return NULL;
}
int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry,
		struct inode *_dst_dir, struct dentry *_dst_dentry)
{
	int err, flags;
	/* reduce stack space */
	struct au_ren_args *a;

	AuDbg("%.*s, %.*s\n", AuDLNPair(_src_dentry), AuDLNPair(_dst_dentry));
	IMustLock(_src_dir);
	IMustLock(_dst_dir);

	err = -ENOMEM;
	BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE);
	a = kzalloc(sizeof(*a), GFP_NOFS);
	if (unlikely(!a))
		goto out;

	a->src_dir = _src_dir;
	a->src_dentry = _src_dentry;
	a->src_inode = a->src_dentry->d_inode;
	a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */
	a->dst_dir = _dst_dir;
	a->dst_dentry = _dst_dentry;
	a->dst_inode = a->dst_dentry->d_inode;
	a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */
	if (a->dst_inode) {
		IMustLock(a->dst_inode);
		au_igrab(a->dst_inode);
	}

	err = -ENOTDIR;
	flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN;
	if (S_ISDIR(a->src_inode->i_mode)) {
		au_fset_ren(a->flags, ISDIR);
		if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode)))
			goto out_free;
		err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
						AuLock_DIR | flags);
	} else
		err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry,
						flags);
	if (unlikely(err))
		goto out_free;

	err = au_d_hashed_positive(a->src_dentry);
	if (unlikely(err))
		goto out_unlock;
	err = -ENOENT;
	if (a->dst_inode) {
		/*
		 * If it is a dir, VFS unhash dst_dentry before this
		 * function. It means we cannot rely upon d_unhashed().
		 */
		if (unlikely(!a->dst_inode->i_nlink))
			goto out_unlock;
		if (!S_ISDIR(a->dst_inode->i_mode)) {
			err = au_d_hashed_positive(a->dst_dentry);
			if (unlikely(err))
				goto out_unlock;
		} else if (unlikely(IS_DEADDIR(a->dst_inode)))
			goto out_unlock;
	} else if (unlikely(d_unhashed(a->dst_dentry)))
		goto out_unlock;

	au_fset_ren(a->flags, ISSAMEDIR); /* temporary */
	di_write_lock_parent(a->dst_parent);

	/* which branch we process */
	err = au_ren_wbr(a);
	if (unlikely(err < 0))
		goto out_parent;
	a->br = au_sbr(a->dst_dentry->d_sb, a->btgt);
	a->h_path.mnt = a->br->br_mnt;

	/* are they available to be renamed */
	err = au_ren_may_dir(a);
	if (unlikely(err))
		goto out_children;

	/* prepare the writable parent dir on the same branch */
	if (a->dst_bstart == a->btgt) {
		au_fset_ren(a->flags, WHDST);
	} else {
		err = au_cpup_dirs(a->dst_dentry, a->btgt);
		if (unlikely(err))
			goto out_children;
	}

	if (a->src_dir != a->dst_dir) {
		/*
		 * this temporary unlock is safe,
		 * because both dir->i_mutex are locked.
		 */
		di_write_unlock(a->dst_parent);
		di_write_lock_parent(a->src_parent);
		err = au_wr_dir_need_wh(a->src_dentry,
					au_ftest_ren(a->flags, ISDIR),
					&a->btgt);
		di_write_unlock(a->src_parent);
		di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1);
		au_fclr_ren(a->flags, ISSAMEDIR);
	} else
		err = au_wr_dir_need_wh(a->src_dentry,
					au_ftest_ren(a->flags, ISDIR),
					&a->btgt);
	if (unlikely(err < 0))
		goto out_children;
	if (err)
		au_fset_ren(a->flags, WHSRC);

	/* lock them all */
	err = au_ren_lock(a);
	if (unlikely(err))
		goto out_children;

	if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE))
		err = au_may_ren(a);
	else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN))
		err = -ENAMETOOLONG;
	if (unlikely(err))
		goto out_hdir;

	/* store timestamps to be revertible */
	au_ren_dt(a);

	/* here we go */
	err = do_rename(a);
	if (unlikely(err))
		goto out_dt;

	/* update dir attributes */
	au_ren_refresh_dir(a);

	/* dput/iput all lower dentries */
	au_ren_refresh(a);

	goto out_hdir; /* success */

out_dt:
	au_ren_rev_dt(err, a);
out_hdir:
	au_ren_unlock(a);
out_children:
	au_nhash_wh_free(&a->whlist);
	if (err && a->dst_inode && a->dst_bstart != a->btgt) {
		AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt);
		au_set_h_dptr(a->dst_dentry, a->btgt, NULL);
		au_set_dbstart(a->dst_dentry, a->dst_bstart);
	}
out_parent:
	if (!err)
		d_move(a->src_dentry, a->dst_dentry);
	else {
		au_update_dbstart(a->dst_dentry);
		if (!a->dst_inode)
			d_drop(a->dst_dentry);
	}
	if (au_ftest_ren(a->flags, ISSAMEDIR))
		di_write_unlock(a->dst_parent);
	else
		di_write_unlock2(a->src_parent, a->dst_parent);
out_unlock:
	aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry);
out_free:
	iput(a->dst_inode);
	if (a->thargs)
		au_whtmp_rmdir_free(a->thargs);
	kfree(a);
out:
	AuTraceErr(err);
	return err;
}
Esempio n. 24
0
void veh_interact::exec (game *gm, vehicle *v, int x, int y)
{
    g = gm;
    veh = v;
    ex = x;
    ey = y;
    //        x1      x2
    // y1 ----+------+--
    //        |      |
    // y2 ----+------+
    //               |
    //               |
    winw1 = 12;
    winw2 = 35;
    winh1 = 3;
    winh2 = 12;
    winw12 = winw1 + winw2 + 1;
    winw3 = 80 - winw1 - winw2 - 2;
    winh3 = 25 - winh1 - winh2 - 2;
    winh23 = winh2 + winh3 + 1;
    winx1 = winw1;
    winx2 = winw1 + winw2 + 1;
    winy1 = winh1;
    winy2 = winh1 + winh2 + 1;

    page_size = winh23;
    //               h   w    y     x
    w_grid  = newwin(25, 80,  0,    0);
    w_mode  = newwin(1,  80, 0,    0);
    w_msg   = newwin(winh1 - 1, 80, 1,    0);
    w_disp  = newwin(winh2, winw1,  winy1 + 1, 0);
    w_parts = newwin(winh2, winw2,  winy1 + 1, winx1 + 1);
    w_stats = newwin(winh3, winw12, winy2 + 1, 0);
    w_list  = newwin(winh23, winw3, winy1 + 1, winx2 + 1);

    for (int i = 0; i < 25; i++)
    {
        mvwputch(w_grid, i, winx2, c_ltgray, i == winy1 || i == winy2? LINE_XOXX : LINE_XOXO);
        if (i >= winy1 && i < winy2)
            mvwputch(w_grid, i, winx1, c_ltgray, LINE_XOXO);
    }
    for (int i = 0; i < 80; i++)
    {
        mvwputch(w_grid, winy1, i, c_ltgray, i == winx1? LINE_OXXX : (i == winx2? LINE_OXXX : LINE_OXOX));
        if (i < winx2)
            mvwputch(w_grid, winy2, i, c_ltgray, i == winx1? LINE_XXOX : LINE_OXOX);
    }
    wrefresh(w_grid);

    crafting_inv = gm->crafting_inventory();

    int charges = ((it_tool *) g->itypes["welder"])->charges_per_use;
    has_wrench = crafting_inv.has_amount("wrench", 1) ||
                 crafting_inv.has_amount("toolset", 1);
    has_hacksaw = crafting_inv.has_amount("hacksaw", 1) ||
                  crafting_inv.has_amount("toolset", 1);
    has_welder = (crafting_inv.has_amount("welder", 1) &&
                  crafting_inv.has_charges("welder", charges)) ||
                 (crafting_inv.has_amount("toolset", 1) &&
                 crafting_inv.has_charges("toolset", charges/5));

    display_stats ();
    display_veh   ();
    move_cursor (0, 0);
    bool finish = false;
    while (!finish)
    {
        char ch = input(); // See keypress.h
        int dx, dy;
        get_direction (gm, dx, dy, ch);
        if (ch == KEY_ESCAPE)
            finish = true;
        else
        if (dx != -2 && (dx || dy) &&
            cx + dx >= -6 && cx + dx < 6 &&
            cy + dy >= -6 && cy + dy < 6)
            move_cursor(dx, dy);
        else
        {
            int mval = cant_do(ch);
            display_mode (ch);
            switch (ch)
            {
            case 'i': do_install(mval); break;
            case 'r': do_repair(mval);  break;
            case 'f': do_refill(mval);  break;
            case 'o': do_remove(mval);  break;
            case 'e': do_rename(mval);  break;
            default:;
            }
            if (sel_cmd != ' ')
                finish = true;
            display_mode (' ');
        }
    }
    werase(w_grid);
    werase(w_mode);
    werase(w_msg);
    werase(w_disp);
    werase(w_parts);
    werase(w_stats);
    werase(w_list);
    delwin(w_grid);
    delwin(w_mode);
    delwin(w_msg);
    delwin(w_disp);
    delwin(w_parts);
    delwin(w_stats);
    delwin(w_list);
    erase();
}
Esempio n. 25
0
File: delete.c Progetto: EmisFR/burp
// The failure conditions here are dealt with by the rubble cleaning code.
static int delete_backup(struct sdirs *sdirs, const char *cname, struct bu *bu,
	const char *manual_delete)
{
	logp("deleting %s backup %"PRId64"\n", cname, bu->bno);

	if(sdirs->global_sparse)
	{
		const char *candidate_str=bu->path+strlen(sdirs->base)+1;
		if(remove_from_global_sparse(
			sdirs->global_sparse, candidate_str))
				return -1;
	}

	if(!bu->next && !bu->prev)
	{
		// The current, and only, backup.
		if(do_rename_w(bu->path, sdirs->deleteme, cname, bu))
			return -1;
		// If interrupted here, there will be a dangling 'current'
		// symlink.
		if(unlink(sdirs->current))
		{
			logp("unlink %s: %s\n",
				sdirs->current, strerror(errno));
			return -1;
		}
		return recursive_delete_w(sdirs, bu, manual_delete);
	}
	if(!bu->next && bu->prev)
	{
		// The current backup. There are other backups left.
		// Need to point the symlink at the previous backup.
		const char *target=NULL;
		
		target=bu->prev->basename;
		unlink(sdirs->currenttmp);
		if(symlink(target, sdirs->currenttmp))
		{
			logp("could not symlink '%s' to '%s': %s\n",
				sdirs->currenttmp, target, strerror(errno));
			return -1;
		}
		// If interrupted here, there is a currenttmp and a current
		// symlink, and they both point to valid directories.
		if(do_rename_w(bu->path, sdirs->deleteme, cname, bu))
			return -1;
		// If interrupted here, there is a currenttmp and a current
		// symlink, and the current link is dangling.
		if(do_rename(sdirs->currenttmp, sdirs->current))
			return -1;
		// If interrupted here, moving the symlink could have failed
		// after current was deleted but before currenttmp was renamed.
		if(recursive_delete_w(sdirs, bu, manual_delete))
			return -1;
		return 0;
	}

	// It is not the current backup.
	if(do_rename_w(bu->path, sdirs->deleteme, cname, bu)
	  || recursive_delete_w(sdirs, bu, manual_delete))
		return -1;
	return 0;
}
Esempio n. 26
0
static char *convert_name(char *name, struct stat *st, cnid_t cur_did)
{
	static char   buffer[MAXPATHLEN +2];  /* for convert_charset dest_len parameter +2 */
	size_t outlen = 0;
	unsigned char *p,*q;
	int require_conversion = 0;
    u_int16_t    flags = conv_flags;
	cnid_t id;

	p = (unsigned char *)name;
	q = (unsigned char *)buffer;

	/* optimize for ascii case */
	while (*p != 0) {
		if ( *p >= 0x80 || *p == ':') {
			require_conversion = 1;
			break;
		}
		p++;
	}

	if (!require_conversion) {
		if (verbose > 1)
		    fprintf(stdout, "no conversion required\n");
		return name;
	}

	/* convert charsets */
	q=(unsigned char *)buffer;
	p=(unsigned char *)name;

	outlen = convert_charset(ch_from, ch_to, ch_mac, (char *)p, strlen((char *)p), (char *)q, sizeof(buffer) -2, &flags);
	if ((size_t)-1 == outlen) {
  	   if ( ch_to == CH_UTF8) {
		/* maybe name is already in UTF8? */
		flags = conv_flags;
		q = (unsigned char *)buffer;
		p = (unsigned char *)name;
		outlen = convert_charset(ch_to, ch_to, ch_mac, (char *)p, strlen((char *)p), (char *)q, sizeof(buffer) -2, &flags);
		if ((size_t)-1 == outlen) {
			/* it's not UTF8... */
        		fprintf(stderr, "ERROR: conversion from '%s' to '%s' for '%s' in DID %u failed!!!\n", 
                  		from_charset, to_charset, name, ntohl(cur_did));
			return name;
		}

		if (!strcmp(buffer, name)) {
	   		return name;
		}
           }
 	   fprintf(stderr, "ERROR: conversion from '%s' to '%s' for '%s' in DID %u failed. Please check this!\n", 
                  	from_charset, to_charset, name, ntohl(cur_did));
	   return name;
	}

	if (strcmp (name, buffer)) {
	    if (dry_run) {
    		fprintf(stdout, "dry_run: would rename %s to %s.\n", name, buffer);
	    }	
	    else if (!do_rename(name, buffer, st)) {
		if (CNID_INVALID != (id = cnid_add(cdb, st, cur_did, buffer, strlen(buffer), 0))) 
       	    		fprintf(stdout, "converted '%s' to '%s' (ID %u, DID %u).\n", 
                                name, buffer, ntohl(id), ntohl(cur_did));
	    }
	}
	else if (verbose > 1)
	    fprintf(stdout, "no conversion required\n");
	
	return (buffer);
}
Esempio n. 27
0
static int do_backup_server(struct async *as, struct sdirs *sdirs,
	struct conf **cconfs, const char *incexc, int resume)
{
	int ret=0;
	int do_phase2=1;
	struct asfd *asfd=as->asfd;
	enum protocol protocol=get_protocol(cconfs);
	struct cntr *cntr=get_cntr(cconfs);

	logp("in do_backup_server\n");

	log_rshash(cconfs);

	if(resume)
	{
		if(sdirs_get_real_working_from_symlink(sdirs)
		  || sdirs_get_real_manifest(sdirs, protocol)
		  || open_log(asfd, sdirs, cconfs))
			goto error;
	}
	else
	{
		// Not resuming - need to set everything up fresh.
		if(sdirs_create_real_working(sdirs,
			get_string(cconfs[OPT_TIMESTAMP_FORMAT]))
		  || sdirs_get_real_manifest(sdirs, protocol)
		  || open_log(asfd, sdirs, cconfs))
			goto error;

		if(write_incexc(sdirs->rworking, incexc))
		{
			logp("unable to write incexc\n");
			goto error;
		}

		if(backup_phase1_server(as, sdirs, cconfs))
		{
			logp("error in phase 1\n");
			goto error;
		}
	}

	if(resume)
	{
		struct stat statp;
		if(lstat(sdirs->phase1data, &statp)
		  && !lstat(sdirs->changed, &statp)
		  && !lstat(sdirs->unchanged, &statp))
		{
			// In this condition, it looks like there was an
			// interruption during phase3. Skip phase2.
			do_phase2=0;
		}
	}

	if(do_phase2)
	{
		if(backup_phase2_server(as, sdirs, incexc, resume, cconfs))
		{
			logp("error in backup phase 2\n");
			goto error;
		}

		asfd->write_str(asfd, CMD_GEN, "okbackupend");
	}

	// Close the connection with the client, the rest of the job we can do
	// by ourselves.
	logp("Backup ending - disconnect from client.\n");
	if(asfd_flush_asio(asfd)) goto end;
	as->asfd_remove(as, asfd);
	asfd_close(asfd);

	if(backup_phase3_server(sdirs, cconfs))
	{
		logp("error in backup phase 3\n");
		goto error;
	}

	if(do_rename(sdirs->working, sdirs->finishing))
		goto error;

	if(backup_phase4_server(sdirs, cconfs))
	{
		logp("error in backup phase 4\n");
		goto error;
	}

	cntr_print(cntr, ACTION_BACKUP, asfd);
	cntr_stats_to_file(cntr, sdirs->rworking, ACTION_BACKUP);

	if(protocol==PROTO_2)
	{
		// Regenerate dindex before the symlink is renamed, so that the
		// champ chooser cleanup does not try to remove data files
		// whilst the dindex regeneration is happening.
		if(regenerate_client_dindex(sdirs))
			goto error;
	}

	// Move the symlink to indicate that we are now in the end phase. The
	// rename() race condition is automatically recoverable here.
	if(do_rename(sdirs->finishing, sdirs->current))
		goto error;

	logp("Backup completed.\n");
	log_fzp_set(NULL, cconfs);
	compress_filename(sdirs->rworking,
		"log", "log.gz", get_int(cconfs[OPT_COMPRESSION]));

	goto end;
error:
	ret=-1;
end:

	log_fzp_set(NULL, cconfs);
	return ret;
}
Esempio n. 28
0
/* Rewrite the config file with the ssl_peer_cn value changed to what the
   server told us it should be. */
static int rewrite_client_conf(struct config *conf)
{
	int ret=-1;
	char p[32]="";
	FILE *dp=NULL;
	FILE *sp=NULL;
	char *tmp=NULL;
	char buf[4096]="";

	logp("Rewriting config file: %s\n", conf->configfile);
	snprintf(p, sizeof(p), ".%d", getpid());
	if(!(tmp=prepend(conf->configfile, p, strlen(p), "")))
		goto end;
	if(!(sp=open_file(conf->configfile, "rb"))
	  || !(dp=open_file(tmp, "wb")))
		goto end;

	while(fgets(buf, sizeof(buf), sp))
	{
		char *copy=NULL;
		char *field=NULL;
		char *value=NULL;

		if(!(copy=strdup(buf)))
		{
			logp("out of memory\n");
			goto end;
		}
		if(config_get_pair(buf, &field, &value)
		  || !field || !value
		  || strcmp(field, "ssl_peer_cn"))
		{
			fprintf(dp, "%s", copy);
			free(copy);
			continue;
		}
		free(copy);

		fprintf(dp, "ssl_peer_cn = %s\n", conf->ssl_peer_cn);
	}
	close_fp(&sp);
	if(close_fp(&dp))
	{
		logp("error closing %s in rewrite_client_conf\n", tmp);
		ret=-1;
		goto end;
	}
#ifdef HAVE_WIN32
	// Need to delete the destination, or Windows gets upset.
	unlink(conf->configfile);
#endif
	if(do_rename(tmp, conf->configfile)) goto end;

	ret=0;
end:
	close_fp(&sp);
	close_fp(&dp);
	if(ret)
	{
		logp("Rewrite failed\n");
		unlink(tmp);
	}
	if(tmp) free(tmp);
	return ret;
}
Esempio n. 29
0
int vfs_selftest(kshell_t *kshell, int argc, char **argv)
{
  int fd1,fd2;
  char *y="/ab/fil";
  char x[2];
  int err;
  do_mkdir("/ab");
  do_mknod("/ab/new", S_IFCHR,MKDEVID(1,1));
  fd1=do_open("/ab/new",2);
  fd2=do_dup2(fd1,NFILES+1);
  if(fd2<0)
    {
      dbg(DBG_PRINT,"File not created\n");
    }
  do_mknod("/ab/notmade",4096,MKDEVID(1,1));
  do_mknod("/ab/new/not",S_IFCHR,MKDEVID(1,1));
  do_mknod("/ab/new", S_IFCHR,MKDEVID(1,1));
  do_mknod("", S_IFCHR,MKDEVID(1,1));

  /*do_close(fd1);*/
    for(fd2=1;fd2<35;fd2++)
    {
      sprintf(x,"%d",fd2);
      strcat(y,x);
      do_mknod(y,S_IFCHR,MKDEVID(1,0));
      err=do_open(y,2);
      if(err<0)
	{
	  break;
	}
      if(fd2<10)
	{
	  y[strlen(y)-1]='\0';
	}
      else
	{
	   y[strlen(y)-2]='\0';
	}
      
    }
do_mknod("/ab/new1", S_IFCHR,MKDEVID(1,1));
 err=do_dup(fd1);
  do_unlink("/ab/new/ab");
 do_unlink("/ab/new");
 do_close(fd1);
 for(fd2=NFILES-1;fd2>0;fd2--)
   {
     err=do_close(fd2);
     sprintf(x,"%d",fd2);
      strcat(y,x);
      do_unlink(y);  
      if(err<0)
	{
	  break;
	}
      if(fd2<10)
	{
	  y[strlen(y)-1]='\0';
	}
      else
	{
	   y[strlen(y)-2]='\0';
	}
   }
 do_link("/a","/dev");
 do_link("/dev","/a");
 do_link("/dev","/a");
 do_rmdir("/a");
 /* mkdir("/k");
    do_link("/ab","/k");*/
  do_rmdir("/ab");
  /*do_rmdir("/k");*/

 /*GS: SELF TESTS*/
    dbg(DBG_PRINT,"\n*************************************************************\n");
    dbg(DBG_PRINT,"\n\n\n\n(GRADING2C)(kmain.c)(selftest_proc_run) selftests begin\n");

    int retVal = 0;
    int i = 0;

    /* 1. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_stat)  strlen too long, return -ENAMETOOLONG\n");*/
    char longPath[1024 + 1] = {0};
    for(i = 0; i < 1025; i++)
        longPath[i] = 'a';
    struct stat buf;
    retVal = do_stat(longPath, &buf);
    retVal=do_chdir(longPath);

    /*2. dbg(DBG_PRINT, "(GRADING2B) ENOTDIR or ENOENT\n");*/
    retVal = do_stat("", &buf);

    /*3. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) Invalid file descriptor fd, return -EBADF\n");*/
    struct dirent dirp;
    retVal = do_getdent(-1, &dirp);

    /*4. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) Invalid file descriptor fd, return -EBADF\n");*/
    retVal = do_getdent(1, &dirp);

    /*5. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) File descriptor does not refer to a directory, return -ENOTDIR\n");*/
    do_mknod("/./file", S_IFCHR,MKDEVID(1,1));
    fd1 = do_open("/./file",2);
    retVal = do_getdent(fd1, &dirp);

    do_unlink("/./file");
    do_close(fd1);
    /*6. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_rename) Both are valid names \n");*/
    /* and */
    /*7. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_rename) error do_link, return error\n"); \n");*/
    retVal = do_rename("/./aaa", "/./bbb");


    dbg(DBG_PRINT,"\n\nretVal=%d",retVal);
    dbg(DBG_PRINT,"\n*************************************************************\n");
  return 0;
}
Esempio n. 30
0
static int jiggle(struct sdirs *sdirs, struct fdirs *fdirs, struct sbuf *sb,
	int hardlinked_current, const char *deltabdir, const char *deltafdir,
	const char *sigpath, FILE **delfp, struct conf *cconf)
{
	int ret=-1;
	struct stat statp;
	char *oldpath=NULL;
	char *newpath=NULL;
	char *finpath=NULL;
	char *deltafpath=NULL;
	const char *datapth=sb->burp1->datapth.buf;

	// If the previous backup was a hardlinked_archive, there will not be
	// a currentdup directory - just directly use the file in the previous
	// backup.
	if(!(oldpath=prepend_s(hardlinked_current?
		sdirs->currentdata:fdirs->currentdupdata, datapth))
	  || !(newpath=prepend_s(fdirs->datadirtmp, datapth))
	  || !(finpath=prepend_s(fdirs->datadir, datapth))
	  || !(deltafpath=prepend_s(deltafdir, datapth)))
		goto end;

	if(!lstat(finpath, &statp) && S_ISREG(statp.st_mode))
	{
		// Looks like an interrupted jiggle
		// did this file already.
		static int donemsg=0;
		if(!lstat(deltafpath, &statp) && S_ISREG(statp.st_mode))
		{
			logp("deleting unneeded forward delta: %s\n",
				deltafpath);
			unlink(deltafpath);
		}
		if(!donemsg)
		{
			logp("skipping already present file: %s\n", finpath);
			logp("to save log space, skips of other already present files will not be logged\n");
			donemsg++;
		}
	}
	else if(mkpath(&finpath, fdirs->datadir))
	{
		logp("could not create path for: %s\n", finpath);
		goto end;
	}
	else if(mkpath(&newpath, fdirs->datadirtmp))
	{
		logp("could not create path for: %s\n", newpath);
		goto end;
	}
	else if(!lstat(deltafpath, &statp) && S_ISREG(statp.st_mode))
	{
		int lrs;
		char *infpath=NULL;

		// Got a forward patch to do.
		// First, need to gunzip the old file,
		// otherwise the librsync patch will take
		// forever, because it will be doing seeks
		// all over the place, and gzseeks are slow.
	  	if(!(infpath=prepend_s(deltafdir, "inflate")))
		{
			log_out_of_memory(__func__);
			goto end;
		}

		//logp("Fixing up: %s\n", datapth);
		if(inflate_or_link_oldfile(oldpath, infpath,
			sb->compression, cconf))
		{
			logp("error when inflating old file: %s\n", oldpath);
			free(infpath);
			goto end;
		}

		if((lrs=do_patch(NULL, infpath, deltafpath, newpath,
			cconf->compression,
			sb->compression /* from the manifest */, cconf)))
		{
			logp("WARNING: librsync error when patching %s: %d\n",
				oldpath, lrs);
			cntr_add(cconf->cntr, CMD_WARNING, 1);
			// Try to carry on with the rest of the backup
			// regardless.
			//ret=-1;
			// Remove anything that got written.
			unlink(newpath);
			unlink(infpath);
			free(infpath);

			// First, note that we want to remove this entry from
			// the manifest.
			if(!*delfp
			  && !(*delfp=open_file(fdirs->deletionsfile, "ab")))
			{
				// Could not mark this file as deleted. Fatal.
				goto end;
			}
			if(sbufl_to_manifest(sb, *delfp, NULL))
				goto end;
			if(fflush(*delfp))
			{
				logp("error fflushing deletions file in %s: %s\n", __func__, strerror(errno));
				goto end;
			}
	
			ret=0;
			goto end;
		}

		// Get rid of the inflated old file.
		unlink(infpath);
		free(infpath);

		// Need to generate a reverse diff, unless we are keeping a
		// hardlinked archive.
		if(!hardlinked_current)
		{
			if(gen_rev_delta(sigpath, deltabdir,
				oldpath, newpath, datapth, sb, cconf))
					goto end;
		}

		// Power interruptions should be recoverable. If it happens
		// before this point, the data jiggle for this file has to be
		// done again.
		// Once finpath is in place, no more jiggle is required.

		// Use the fresh new file.
		// Rename race condition is of no consequence, because finpath
		// will just get recreated automatically.
		if(do_rename(newpath, finpath))
			goto end;

		// Remove the forward delta, as it is no longer needed. There
		// is a reverse diff and the finished finished file is in place.
		//logp("Deleting delta.forward...\n");
		unlink(deltafpath);

		// Remove the old file. If a power cut happens just before
		// this, the old file will hang around forever.
		// FIX THIS: maybe put in something to detect this.
		// ie, both a reverse delta and the old file exist.
		if(!hardlinked_current)
		{
			//logp("Deleting oldpath...\n");
			unlink(oldpath);
		}
	}
	else if(!lstat(newpath, &statp) && S_ISREG(statp.st_mode))
	{
		// Use the fresh new file.
		// This needs to happen after checking
		// for the forward delta, because the
		// patching stuff writes to newpath.

		// Rename race condition is of no consequence, because finpath
		// will just get recreated automatically.

		//logp("Using newly received file\n");
		if(do_rename(newpath, finpath))
			goto end;
	}
	else if(!lstat(oldpath, &statp) && S_ISREG(statp.st_mode))
	{
		// Use the old unchanged file.
		// Hard link it first.
		//logp("Hard linking to old file: %s\n", datapth);
		if(do_link(oldpath, finpath, &statp, cconf,
		  0 /* do not overwrite finpath (should never need to) */))
			goto end;
		else
		{
			// If we are not keeping a hardlinked
			// archive, delete the old link.
			if(!hardlinked_current)
			{
				//logp("Unlinking old file: %s\n", oldpath);
				unlink(oldpath);
			}
		}
	}
	else
	{
		logp("could not find: %s\n", oldpath);
		goto end;
	}

	ret=0;
end:
	free_w(&oldpath);
	free_w(&newpath);
	free_w(&finpath);
	free_w(&deltafpath);
	return ret;
}