Esempio n. 1
0
int get_new_timestamp(struct config *cconf, const char *basedir, char *buf, size_t s)
{
	int a=0;
	time_t t=0;
	const struct tm *ctm=NULL;
	unsigned long index=0;
	char tmpbuf[32]="";
	struct bu *arr=NULL;

	// Want to prefix the timestamp with an index that increases by
	// one each time. This makes it far more obvious which backup depends
	// on which - even if the system clock moved around. Take that,
	// bacula!

	// get_current_backups orders the array with the highest index number 
	// last
	if(get_current_backups(basedir, &arr, &a, 1)) return -1;
	if(a) index=arr[a-1].index;

	free_current_backups(&arr, a);

	time(&t);
	ctm=localtime(&t);
        // Windows does not like the %T strftime format option - you get
        // complaints under gdb.
	strftime(tmpbuf, sizeof(tmpbuf), cconf->timestamp_format, ctm);
	snprintf(buf, s, "%07lu %s", ++index, tmpbuf);

	return 0;
}
Esempio n. 2
0
int do_remove_old_backups(const char *basedir, struct config *cconf, const char *client)
{
	int a=0;
	int b=0;
        int x=0;
	int ret=0;
	int deleted=0;
	unsigned long m=1;
	struct bu *arr=NULL;
	struct strlist **kplist=NULL;

	kplist=cconf->keep;

	if(get_current_backups(basedir, &arr, &a, 1)) return -1;

	// For each of the 'keep' values, generate ranges in which to keep
	// one backup.
        for(x=0; x<cconf->kpcount; x++)
        {
		unsigned long n=0;
		n=m * kplist[x]->flag;

                //printf("keep[%d]: %d - m:%lu n:%lu\n",
		//	x, cconf->keep[x]->flag, m, n);
		if(x+1 < cconf->kpcount)
		{
			unsigned long r=0;
			unsigned long s=0;
			unsigned long upto=0;
			upto=n*cconf->keep[x+1]->flag;
			//printf("upto: %lu\n", upto);
			// This is going over each range.
			for(r=upto; r>n; r-=n)
			{
				int count=0;
				s=r-n;
				//printf("   try: %lu - %lu\n", s, r);

				// Count the backups in the range.
				for(b=0; b<a; b++)
				{
					if(s<arr[b].trindex
					   && arr[b].trindex<=r)
					{
						//printf("     check backup %lu (%lu) %d\n", arr[b].index, arr[b].trindex, arr[b].deletable);
						count++;
					}
				}

				// Want to leave one entry in each range.
				if(count>1)
				{
				  // Try to delete from the most recent in each
				  // so that hardlinked backups get taken out
				  // last.
				  
				  for(b=a-1; b>=0; b--)
				  {
				    if(s<arr[b].trindex
				       && arr[b].trindex<=r
				       && arr[b].deletable)
				    {
					//printf("deleting backup %lu (%lu)\n", arr[b].index, arr[b].trindex);
					if(delete_backup(basedir, arr,
						a, b, client))
					{
						ret=-1;
						break;
					}
					deleted++;
				  	if(--count<=1) break;
				    }
				  }
				}

				if(ret) break;
			}
		}
		m=n;

		if(ret) break;
        }

	if(!ret)
	{
		// Remove the very oldest backups.
		//printf("back from: %lu\n", m);
		for(b=0; b<a; b++)
		{
			//printf(" %d: %lu (%lu)\n", b, arr[b].index, arr[b].trindex);
			if(arr[b].trindex>m) break;
		}
		for(; b>=0 && b<a; b--)
		{
			if(delete_backup(basedir, arr, a, b, client))
			{
				ret=-1;
				break;
			}
			deleted++;
		}
	}

	free_current_backups(&arr, a);

	if(ret) return ret;

	return deleted;
}
Esempio n. 3
0
int do_list_server(const char *basedir, const char *backup, const char *listregex, const char *browsedir, const char *client, struct cntr *p1cntr, struct cntr *cntr)
{
	int a=0;
	int i=0;
	int ret=0;
	int found=0;
	struct bu *arr=NULL;
	unsigned long index=0;
	regex_t *regex=NULL;

	logp("in do_list\n");

	if(compile_regex(&regex, listregex)) return -1;

	if(get_current_backups(basedir, &arr, &a, 1))
	{
		if(regex) { regfree(regex); free(regex); }
		return -1;
	}

	write_status(client, STATUS_LISTING, NULL, p1cntr, cntr);

	if(backup && *backup) index=strtoul(backup, NULL, 10);

	for(i=0; i<a; i++)
	{
		// Search all backups for things matching the regex.
		if(listregex && backup && *backup=='a')
		{
			found=TRUE;
			async_write(CMD_TIMESTAMP,
				arr[i].timestamp, strlen(arr[i].timestamp));
			ret+=list_manifest(arr[i].path, regex, browsedir,
				client, p1cntr, cntr);
		}
		// Search or list a particular backup.
		else if(backup && *backup)
		{
			if(!found
			  && (!strcmp(arr[i].timestamp, backup)
				|| arr[i].index==index))
			{
				found=TRUE;
				async_write(CMD_TIMESTAMP,
				  arr[i].timestamp, strlen(arr[i].timestamp));
				ret=list_manifest(arr[i].path, regex,
					browsedir, client, p1cntr, cntr);
			}
		}
		// List the backups.
		else
		{
			found=TRUE;
			async_write(CMD_TIMESTAMP,
				arr[i].timestamp, strlen(arr[i].timestamp));
		}
	}
	free_current_backups(&arr, a);

	if(backup && *backup && !found)
	{
		async_write_str(CMD_ERROR, "backup not found");
		ret=-1;
	}
	if(regex) { regfree(regex); free(regex); }
	return ret;
}
Esempio n. 4
0
int do_restore_server(const char *basedir, enum action act, const char *client, int srestore, char **dir_for_notify, struct cntr *p1cntr, struct cntr *cntr, struct config *cconf)
{
	int a=0;
	int i=0;
	int ret=0;
	int found=0;
	struct bu *arr=NULL;
	unsigned long index=0;
	char *tmppath1=NULL;
	char *tmppath2=NULL;
	regex_t *regex=NULL;

	logp("in do_restore\n");

	if(compile_regex(&regex, cconf->regex)) return -1;

	if(!(tmppath1=prepend_s(basedir, "tmp1", strlen("tmp1")))
	  || !(tmppath2=prepend_s(basedir, "tmp2", strlen("tmp2"))))
	{
		if(tmppath1) free(tmppath1);
		if(regex) { regfree(regex); free(regex); }
		return -1;
	}

	if(get_current_backups(basedir, &arr, &a, 1))
	{
		if(tmppath1) free(tmppath1);
		if(tmppath2) free(tmppath2);
		if(regex) { regfree(regex); free(regex); }
		return -1;
	}

	if(!(index=strtoul(cconf->backup, NULL, 10)) && a>0)
	{
		// No backup specified, do the most recent.
		ret=restore_manifest(arr, a, a-1,
			tmppath1, tmppath2, regex, srestore, act, client,
			dir_for_notify,
			p1cntr, cntr, cconf);
		found=TRUE;
	}

	if(!found) for(i=0; i<a; i++)
	{
		if(!strcmp(arr[i].timestamp, cconf->backup)
			|| arr[i].index==index)
		{
			found=TRUE;
			//logp("got: %s\n", arr[i].path);
			ret|=restore_manifest(arr, a, i,
				tmppath1, tmppath2, regex,
				srestore, act, client, dir_for_notify,
				p1cntr, cntr, cconf);
			break;
		}
	}

	free_current_backups(&arr, a);

	if(!found)
	{
		logp("backup not found\n");
		async_write_str(CMD_ERROR, "backup not found");
		ret=-1;
	}
	if(tmppath1)
	{
		unlink(tmppath1);
		free(tmppath1);
	}
	if(tmppath2)
	{
		unlink(tmppath2);
		free(tmppath2);
	}
	if(regex)
	{
		regfree(regex);
		free(regex);
	}
	return ret;
}
Esempio n. 5
0
int do_restore_server(const char *basedir, const char *backup, const char *restoreregex, enum action act, const char *client, struct cntr *p1cntr, struct cntr *cntr, struct config *cconf)
{
	int a=0;
	int i=0;
	int ret=0;
	int found=0;
	struct bu *arr=NULL;
	unsigned long index=0;
	char *tmppath1=NULL;
	char *tmppath2=NULL;
	regex_t *regex=NULL;
	bool all=FALSE;

	logp("in do_restore\n");

	if(compile_regex(&regex, restoreregex)) return -1;

	if(!(tmppath1=prepend_s(basedir, "tmp1", strlen("tmp1")))
	  || !(tmppath2=prepend_s(basedir, "tmp2", strlen("tmp2"))))
	{
		if(tmppath1) free(tmppath1);
		if(regex) { regfree(regex); free(regex); }
		return -1;
	}

	if(get_current_backups(basedir, &arr, &a, 1))
	{
		if(tmppath1) free(tmppath1);
		if(tmppath2) free(tmppath2);
		if(regex) { regfree(regex); free(regex); }
		return -1;
	}

	if(backup && *backup=='a')
	{
		all=TRUE;
	}
	else if(!(index=strtoul(backup, NULL, 10)) && a>0)
	{
		// No backup specified, do the most recent.
		ret=restore_manifest(arr, a, a-1,
			tmppath1, tmppath2, regex, act, client,
			p1cntr, cntr, cconf, all);
		found=TRUE;
	}

	if(!found) for(i=0; i<a; i++)
	{
		if(all || !strcmp(arr[i].timestamp, backup)
			|| arr[i].index==index)
		{
			found=TRUE;
			//logp("got: %s\n", arr[i].path);
			ret|=restore_manifest(arr, a, i,
				tmppath1, tmppath2, regex, act, client,
				p1cntr, cntr, cconf, all);
			if(!all) break;
		}
	}

	// If doing all backups, send restore end.
	if(!ret && all && found)
		ret=do_restore_end(act, cntr);

	free_current_backups(&arr, a);

	if(!found)
	{
		logp("backup not found\n");
		async_write_str(CMD_ERROR, "backup not found");
		ret=-1;
	}
	if(tmppath1)
	{
		unlink(tmppath1);
		free(tmppath1);
	}
	if(tmppath2)
	{
		unlink(tmppath2);
		free(tmppath2);
	}
	if(regex)
	{
		regfree(regex);
		free(regex);
	}
	return ret;
}