1 #include "burp.h"
2 #include "alloc.h"
3 #include "bu.h"
4 #include "prepend.h"
5 // balh
6 
bu_alloc(void)7 struct bu *bu_alloc(void)
8 {
9 	return (struct bu *)calloc_w(1, sizeof(struct bu), __func__);
10 }
11 
bu_init(struct bu * bu,char * fullpath,char * basename,char * timestampstr,uint16_t flags)12 int bu_init(struct bu *bu, char *fullpath, char *basename,
13 	char *timestampstr, uint16_t flags)
14 {
15 	if(!(bu->data=prepend_s(fullpath, "data"))
16 	  || !(bu->delta=prepend_s(fullpath, "deltas.reverse")))
17 		goto error;
18 	bu->path=fullpath;
19 	bu->basename=basename;
20 	bu->timestamp=timestampstr;
21 	bu->flags=flags;
22 	bu->bno=strtoul(timestampstr, NULL, 10);
23 	return 0;
24 error:
25 	free_w(&bu->data);
26 	free_w(&bu->delta);
27 	return -1;
28 }
29 
bu_free_content(struct bu * bu)30 static void bu_free_content(struct bu *bu)
31 {
32 	if(!bu) return;
33 	free_w(&bu->path);
34 	free_w(&bu->basename);
35 	free_w(&bu->data);
36 	free_w(&bu->delta);
37 	free_w(&bu->timestamp);
38 }
39 
bu_free(struct bu ** bu)40 void bu_free(struct bu **bu)
41 {
42 	if(!bu || !*bu) return;
43 	bu_free_content(*bu);
44 	free_v((void **)bu);
45 }
46 
bu_list_free(struct bu ** bu_list)47 void bu_list_free(struct bu **bu_list)
48 {
49 	struct bu *bu;
50 	struct bu *next;
51 	struct bu *prev=NULL;
52 	if(*bu_list) prev=(*bu_list)->prev;
53 	for(bu=*bu_list; bu; bu=next)
54 	{
55 		next=bu->next;
56 		bu_free(&bu);
57 	}
58 	// Do it in both directions.
59 	for(bu=prev; bu; bu=prev)
60 	{
61 		prev=bu->prev;
62 		bu_free(&bu);
63 	}
64 	*bu_list=NULL;
65 }
66 
bu_find(struct bu * bu,uint16_t flag)67 static struct bu *bu_find(struct bu *bu, uint16_t flag)
68 {
69 	struct bu *cbu=NULL;
70 	if(!bu) return NULL;
71 	if(bu->flags & flag) return bu;
72 	// Search in both directions.
73 	if(bu->next)
74 		for(cbu=bu; cbu; cbu=cbu->next)
75 			if(cbu->flags & flag) return cbu;
76 	if(bu->prev)
77 		for(cbu=bu; cbu; cbu=cbu->prev)
78 			if(cbu->flags & flag) return cbu;
79 	return cbu;
80 }
81 
bu_find_current(struct bu * bu)82 struct bu *bu_find_current(struct bu *bu)
83 {
84 	return bu_find(bu, BU_CURRENT);
85 }
86 
bu_find_working_or_finishing(struct bu * bu)87 struct bu *bu_find_working_or_finishing(struct bu *bu)
88 {
89 	struct bu *cbu=NULL;
90 	if((cbu=bu_find(bu, BU_WORKING))) return cbu;
91 	return bu_find(bu, BU_FINISHING);
92 }
93