Blob
1 #include <u.h>2 #include <libc.h>3 #include <venti.h>4 #include <libsec.h>6 #define MAGIC 0x547983147 #define NOTFREE(p) assert((p)->magic == MAGIC)9 struct Packet10 {11 char *data;12 int len;13 void (*free)(void*);14 void *arg;15 int magic;16 };18 Packet*19 packetalloc(void)20 {21 Packet *p;23 p = vtmallocz(sizeof *p);24 p->free = vtfree;25 p->arg = nil;26 p->magic = MAGIC;27 return p;28 }30 void31 packetappend(Packet *p, uchar *buf, int n)32 {33 NOTFREE(p);34 if(n < 0)35 abort();36 if(p->free != vtfree)37 sysfatal("packetappend");38 p->data = vtrealloc(p->data, p->len+n);39 p->arg = p->data;40 memmove(p->data+p->len, buf, n);41 p->len += n;42 }44 uint45 packetasize(Packet *p)46 {47 NOTFREE(p);48 return p->len;49 }51 int52 packetcmp(Packet *p, Packet *q)53 {54 int i, len;56 NOTFREE(p);57 NOTFREE(q);58 len = p->len;59 if(len > q->len)60 len = q->len;61 if(len && (i=memcmp(p->data, q->data, len)) != 0)62 return i;63 if(p->len > len)64 return 1;65 if(q->len > len)66 return -1;67 return 0;68 }70 void71 packetconcat(Packet *p, Packet *q)72 {73 NOTFREE(p);74 NOTFREE(q);75 packetappend(p, q->data, q->len);76 if(q->free == vtfree)77 memset(q->data, 0xFE, q->len);78 q->free(q->arg);79 q->data = nil;80 q->len = 0;81 }83 int84 packetconsume(Packet *p, uchar *buf, int n)85 {86 NOTFREE(p);87 if(n < 0)88 abort();89 if(p->len < n)90 abort();91 memmove(buf, p->data, n);92 p->len -= n;93 memmove(p->data, p->data+n, p->len);94 return 0;95 }97 int98 packetcopy(Packet *p, uchar *buf, int offset, int n)99 {100 NOTFREE(p);101 if(offset < 0 || n < 0)102 abort();103 if(offset > p->len)104 abort();105 if(offset+n > p->len)106 n = p->len - offset;107 memmove(buf, p->data+offset, n);108 return 0;109 }111 Packet*112 packetdup(Packet *p, int offset, int n)113 {114 Packet *q;116 NOTFREE(p);117 if(offset < 0 || n < 0)118 abort();119 if(offset > p->len)120 abort();121 if(offset+n > p->len)122 n = p->len - offset;123 q = packetalloc();124 packetappend(q, p->data+offset, n);125 return q;126 }128 Packet*129 packetforeign(uchar *buf, int n, void (*free)(void*), void *a)130 {131 Packet *p;133 if(n < 0)134 abort();135 p = packetalloc();136 p->data = (char*)buf;137 p->len = n;138 p->free = free;139 p->arg = a;140 return p;141 }143 int144 packetfragments(Packet *p, IOchunk *io, int nio, int offset)145 {146 NOTFREE(p);147 if(offset < 0)148 abort();149 if(nio == 0)150 return 0;151 memset(io, 0, sizeof(io[0])*nio);152 if(offset >= p->len)153 return 0;154 io[0].addr = p->data + offset;155 io[0].len = p->len - offset;156 return p->len;157 }159 void160 packetfree(Packet *p)161 {162 NOTFREE(p);163 if(p->free == free)164 memset(p->data, 0xFE, p->len);165 p->free(p->arg);166 p->data = nil;167 p->len = 0;168 memset(p, 0xFB, sizeof *p);169 free(p);170 }172 uchar*173 packetheader(Packet *p, int n)174 {175 NOTFREE(p);176 if(n < 0)177 abort();178 if(n > p->len)179 abort();180 return p->data;181 }183 uchar*184 packetpeek(Packet *p, uchar *buf, int offset, int n)185 {186 NOTFREE(p);187 if(offset < 0 || n < 0)188 abort();189 if(offset+n > p->len)190 abort();191 return p->data+offset;192 }194 void195 packetprefix(Packet *p, uchar *buf, int n)196 {197 NOTFREE(p);198 if(n < 0)199 abort();200 if(p->free != free)201 sysfatal("packetappend");202 p->data = vtrealloc(p->data, p->len+n);203 p->arg = p->data;204 memmove(p->data+n, p->data, p->len);205 memmove(p->data, buf, n);206 p->len += n;207 }209 void210 packetsha1(Packet *p, uchar d[20])211 {212 NOTFREE(p);213 sha1((uchar*)p->data, p->len, d, nil);214 }216 uint217 packetsize(Packet *p)218 {219 NOTFREE(p);220 return p->len;221 }223 Packet*224 packetsplit(Packet *p, int n)225 {226 Packet *q;228 NOTFREE(p);229 q = packetalloc();230 q->data = vtmalloc(n);231 q->arg = q->data;232 q->free = vtfree;233 packetconsume(p, q->data, n);234 return q;235 }237 void238 packetstats(void)239 {240 }242 uchar*243 packettrailer(Packet *p, int n)244 {245 NOTFREE(p);246 if(n < 0)247 abort();248 if(n > p->len)249 abort();250 return p->data + p->len - n;251 }253 int254 packettrim(Packet *p, int offset, int n)255 {256 NOTFREE(p);257 if(offset < 0 || n < 0)258 abort();259 if(offset+n > p->len)260 abort();261 memmove(p->data+offset, p->data+offset+n, p->len-offset-n);262 p->len -= n;263 return 0;264 }