1 #include "burp.h"
2 #include "alloc.h"
3 #include "log.h"
4 #include "sbuf.h"
5 #include "slist.h"
6 #include "protocol2/blist.h"
7 
slist_alloc(void)8 struct slist *slist_alloc(void)
9 {
10 	struct slist *slist=NULL;
11 	if(!(slist=(struct slist *)calloc_w(1, sizeof(struct slist), __func__))
12 	  || !(slist->blist=blist_alloc()))
13 		slist_free(&slist);
14 	return slist;
15 }
16 
slist_free(struct slist ** slist)17 void slist_free(struct slist **slist)
18 {
19 	struct sbuf *sb;
20 	struct sbuf *shead;
21 	if(!slist || !*slist)
22 		return;
23 	blist_free(&(*slist)->blist);
24 	shead=(*slist)->head;
25 	while(shead)
26 	{
27 		sb=shead;
28 		shead=shead->next;
29 		sbuf_free(&sb);
30 	}
31 	free_v((void **)slist);
32 }
33 
slist_add_sbuf(struct slist * slist,struct sbuf * sb)34 void slist_add_sbuf(struct slist *slist, struct sbuf *sb)
35 {
36 	if(slist->tail)
37 	{
38 		// Add to the end of the list.
39 		slist->tail->next=sb;
40 		slist->tail=sb;
41 		// Markers might have fallen off the end. Start them again
42 		// on the tail.
43 		if(!slist->last_requested)
44 			slist->last_requested=slist->tail;
45 		if(!slist->add_sigs_here)
46 			slist->add_sigs_here=slist->tail;
47 		if(!slist->blks_to_request)
48 			slist->blks_to_request=slist->tail;
49 		if(!slist->blks_to_send)
50 			slist->blks_to_send=slist->tail;
51 	}
52 	else
53 	{
54 		// Start the list.
55 		slist->head=sb;
56 		slist->tail=sb;
57 		// Pointers to the head that can move along the list
58 		// at a different rate.
59 		slist->last_requested=sb;
60 		slist->add_sigs_here=sb;
61 		slist->blks_to_request=sb;
62 		slist->blks_to_send=sb;
63 	}
64 	slist->count++;
65 }
66 
adjust_dropped_markers(struct slist * slist,struct sbuf * sb)67 static void adjust_dropped_markers(struct slist *slist, struct sbuf *sb)
68 {
69         if(sb==slist->tail)
70 		slist->tail=sb->next;
71         if(sb==slist->last_requested)
72 		slist->last_requested=sb->next;
73         if(sb==slist->add_sigs_here)
74 		slist->add_sigs_here=sb->next;
75         if(sb==slist->blks_to_request)
76 		slist->blks_to_request=sb->next;
77         if(sb==slist->blks_to_send)
78 		slist->blks_to_send=sb->next;
79 }
80 
slist_del_sbuf(struct slist * slist,struct sbuf * sb)81 int slist_del_sbuf(struct slist *slist, struct sbuf *sb)
82 {
83 	struct sbuf *s;
84 	if(!slist)
85 		return 0;
86 	if(sb->protocol2->bstart
87 	  || sb->protocol2->bend
88 	  || sb->protocol2->bsighead)
89 	{
90 		logp("Cannot delete sbuf with blk markers: %s\n",
91 			iobuf_to_printable(&sb->path));
92 		return -1;
93 	}
94 
95 	if(slist->head==sb)
96 	{
97 		// There is one entry in the list.
98 		slist->head=slist->head->next;
99 		slist->count--;
100 	}
101 	else
102 	{
103 		for(s=slist->head; s; s=s->next)
104 		{
105 			if(s->next!=sb) continue;
106 			s->next=sb->next;
107 			if(!sb->next)
108 				slist->tail=s;
109 			slist->count--;
110 			break;
111 		}
112 	}
113 
114         // It is possible for the markers to drop behind.
115 	adjust_dropped_markers(slist, sb);
116 
117 	return 0;
118 }
119 
slist_del_sbuf_by_index(struct slist * slist,uint64_t index)120 int slist_del_sbuf_by_index(struct slist *slist, uint64_t index)
121 {
122 	struct sbuf *sb;
123 	for(sb=slist->head; sb; sb=sb->next)
124 	{
125 		if(sb->protocol2->index==index)
126 		{
127 			if(slist_del_sbuf(slist, sb))
128 				return -1;
129 			sbuf_free(&sb);
130 			break;
131 		}
132 	}
133 	return 0;
134 }
135 
slist_advance(struct slist * slist)136 void slist_advance(struct slist *slist)
137 {
138 	struct sbuf *sb;
139 	sb=slist->head;
140 
141         // It is possible for the markers to drop behind.
142 	adjust_dropped_markers(slist, sb);
143 
144 	slist->head=sb->next;
145 
146 	slist->count--;
147 
148 	sbuf_free(&sb);
149 }
150