17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include "plumb.h"
47dd7cddfSDavid du Colombier
57dd7cddfSDavid du Colombier int
plumbopen(char * name,int omode)67dd7cddfSDavid du Colombier plumbopen(char *name, int omode)
77dd7cddfSDavid du Colombier {
87dd7cddfSDavid du Colombier int fd, f;
99c06fe1dSDavid du Colombier char *s, *plumber;
109c06fe1dSDavid du Colombier char buf[128], err[ERRMAX];
117dd7cddfSDavid du Colombier
127dd7cddfSDavid du Colombier if(name[0] == '/')
137dd7cddfSDavid du Colombier return open(name, omode);
149c06fe1dSDavid du Colombier
159c06fe1dSDavid du Colombier /* find elusive plumber */
16debe080aSDavid du Colombier if(access("/mnt/plumb/send", AWRITE) >= 0)
179c06fe1dSDavid du Colombier plumber = "/mnt/plumb";
18debe080aSDavid du Colombier else if(access("/mnt/term/mnt/plumb/send", AWRITE) >= 0)
199c06fe1dSDavid du Colombier plumber = "/mnt/term/mnt/plumb";
209c06fe1dSDavid du Colombier else{
219c06fe1dSDavid du Colombier /* last resort: try mounting service */
229c06fe1dSDavid du Colombier plumber = "/mnt/plumb";
237dd7cddfSDavid du Colombier s = getenv("plumbsrv");
247dd7cddfSDavid du Colombier if(s == nil)
257dd7cddfSDavid du Colombier return -1;
267dd7cddfSDavid du Colombier f = open(s, ORDWR);
27fed0fa9eSDavid du Colombier free(s);
287dd7cddfSDavid du Colombier if(f < 0)
297dd7cddfSDavid du Colombier return -1;
309c06fe1dSDavid du Colombier if(mount(f, -1, "/mnt/plumb", MREPL, "") < 0){
319c06fe1dSDavid du Colombier close(f);
327dd7cddfSDavid du Colombier return -1;
339c06fe1dSDavid du Colombier }
34debe080aSDavid du Colombier if(access("/mnt/plumb/send", AWRITE) < 0)
359c06fe1dSDavid du Colombier return -1;
369c06fe1dSDavid du Colombier }
379c06fe1dSDavid du Colombier
389c06fe1dSDavid du Colombier snprint(buf, sizeof buf, "%s/%s", plumber, name);
399c06fe1dSDavid du Colombier fd = open(buf, omode);
409c06fe1dSDavid du Colombier if(fd >= 0)
419c06fe1dSDavid du Colombier return fd;
429c06fe1dSDavid du Colombier
439c06fe1dSDavid du Colombier /* try creating port; used by non-standard plumb implementations */
449c06fe1dSDavid du Colombier rerrstr(err, sizeof err);
459c06fe1dSDavid du Colombier fd = create(buf, omode, 0600);
469c06fe1dSDavid du Colombier if(fd >= 0)
479c06fe1dSDavid du Colombier return fd;
489c06fe1dSDavid du Colombier errstr(err, sizeof err);
499c06fe1dSDavid du Colombier
509c06fe1dSDavid du Colombier return -1;
517dd7cddfSDavid du Colombier }
527dd7cddfSDavid du Colombier
537dd7cddfSDavid du Colombier static int
Strlen(char * s)547dd7cddfSDavid du Colombier Strlen(char *s)
557dd7cddfSDavid du Colombier {
567dd7cddfSDavid du Colombier if(s == nil)
577dd7cddfSDavid du Colombier return 0;
587dd7cddfSDavid du Colombier return strlen(s);
597dd7cddfSDavid du Colombier }
607dd7cddfSDavid du Colombier
617dd7cddfSDavid du Colombier static char*
Strcpy(char * s,char * t)627dd7cddfSDavid du Colombier Strcpy(char *s, char *t)
637dd7cddfSDavid du Colombier {
647dd7cddfSDavid du Colombier if(t == nil)
657dd7cddfSDavid du Colombier return s;
667dd7cddfSDavid du Colombier return strcpy(s, t) + strlen(t);
677dd7cddfSDavid du Colombier }
687dd7cddfSDavid du Colombier
697dd7cddfSDavid du Colombier /* quote attribute value, if necessary */
707dd7cddfSDavid du Colombier static char*
quote(char * s,char * buf,char * bufe)71*9b7bf7dfSDavid du Colombier quote(char *s, char *buf, char *bufe)
727dd7cddfSDavid du Colombier {
737dd7cddfSDavid du Colombier char *t;
747dd7cddfSDavid du Colombier int c;
757dd7cddfSDavid du Colombier
767dd7cddfSDavid du Colombier if(s == nil){
77*9b7bf7dfSDavid du Colombier buf[0] = '\0';
78*9b7bf7dfSDavid du Colombier return buf;
797dd7cddfSDavid du Colombier }
807dd7cddfSDavid du Colombier if(strpbrk(s, " '=\t") == nil)
817dd7cddfSDavid du Colombier return s;
82*9b7bf7dfSDavid du Colombier t = buf;
837dd7cddfSDavid du Colombier *t++ = '\'';
84*9b7bf7dfSDavid du Colombier while(t < bufe-2){
857dd7cddfSDavid du Colombier c = *s++;
867dd7cddfSDavid du Colombier if(c == '\0')
877dd7cddfSDavid du Colombier break;
887dd7cddfSDavid du Colombier *t++ = c;
897dd7cddfSDavid du Colombier if(c == '\'')
907dd7cddfSDavid du Colombier *t++ = c;
917dd7cddfSDavid du Colombier }
927dd7cddfSDavid du Colombier *t++ = '\'';
937dd7cddfSDavid du Colombier *t = '\0';
94*9b7bf7dfSDavid du Colombier return buf;
957dd7cddfSDavid du Colombier }
967dd7cddfSDavid du Colombier
977dd7cddfSDavid du Colombier char*
plumbpackattr(Plumbattr * attr)987dd7cddfSDavid du Colombier plumbpackattr(Plumbattr *attr)
997dd7cddfSDavid du Colombier {
1007dd7cddfSDavid du Colombier int n;
1017dd7cddfSDavid du Colombier Plumbattr *a;
102*9b7bf7dfSDavid du Colombier char *s, *t, *buf, *bufe;
1037dd7cddfSDavid du Colombier
1047dd7cddfSDavid du Colombier if(attr == nil)
1057dd7cddfSDavid du Colombier return nil;
106*9b7bf7dfSDavid du Colombier if((buf = malloc(4096)) == nil)
107*9b7bf7dfSDavid du Colombier return nil;
108*9b7bf7dfSDavid du Colombier bufe = buf + 4096;
1097dd7cddfSDavid du Colombier n = 0;
1107dd7cddfSDavid du Colombier for(a=attr; a!=nil; a=a->next)
111*9b7bf7dfSDavid du Colombier n += Strlen(a->name) + 1 + Strlen(quote(a->value, buf, bufe)) + 1;
1127dd7cddfSDavid du Colombier s = malloc(n);
113*9b7bf7dfSDavid du Colombier if(s == nil) {
114*9b7bf7dfSDavid du Colombier free(buf);
1157dd7cddfSDavid du Colombier return nil;
116*9b7bf7dfSDavid du Colombier }
1177dd7cddfSDavid du Colombier t = s;
1187dd7cddfSDavid du Colombier *t = '\0';
1197dd7cddfSDavid du Colombier for(a=attr; a!=nil; a=a->next){
1207dd7cddfSDavid du Colombier if(t != s)
1217dd7cddfSDavid du Colombier *t++ = ' ';
1227dd7cddfSDavid du Colombier strcpy(t, a->name);
1237dd7cddfSDavid du Colombier strcat(t, "=");
124*9b7bf7dfSDavid du Colombier strcat(t, quote(a->value, buf, bufe));
1257dd7cddfSDavid du Colombier t += strlen(t);
1267dd7cddfSDavid du Colombier }
1277dd7cddfSDavid du Colombier if(t > s+n)
1287dd7cddfSDavid du Colombier abort();
129*9b7bf7dfSDavid du Colombier free(buf);
1307dd7cddfSDavid du Colombier return s;
1317dd7cddfSDavid du Colombier }
1327dd7cddfSDavid du Colombier
1337dd7cddfSDavid du Colombier char*
plumblookup(Plumbattr * attr,char * name)1347dd7cddfSDavid du Colombier plumblookup(Plumbattr *attr, char *name)
1357dd7cddfSDavid du Colombier {
1367dd7cddfSDavid du Colombier while(attr){
1377dd7cddfSDavid du Colombier if(strcmp(attr->name, name) == 0)
1387dd7cddfSDavid du Colombier return attr->value;
1397dd7cddfSDavid du Colombier attr = attr->next;
1407dd7cddfSDavid du Colombier }
1417dd7cddfSDavid du Colombier return nil;
1427dd7cddfSDavid du Colombier }
1437dd7cddfSDavid du Colombier
1447dd7cddfSDavid du Colombier char*
plumbpack(Plumbmsg * m,int * np)1457dd7cddfSDavid du Colombier plumbpack(Plumbmsg *m, int *np)
1467dd7cddfSDavid du Colombier {
1477dd7cddfSDavid du Colombier int n, ndata;
1487dd7cddfSDavid du Colombier char *buf, *p, *attr;
1497dd7cddfSDavid du Colombier
1507dd7cddfSDavid du Colombier ndata = m->ndata;
1517dd7cddfSDavid du Colombier if(ndata < 0)
1527dd7cddfSDavid du Colombier ndata = Strlen(m->data);
1537dd7cddfSDavid du Colombier attr = plumbpackattr(m->attr);
1547dd7cddfSDavid du Colombier n = Strlen(m->src)+1 + Strlen(m->dst)+1 + Strlen(m->wdir)+1 +
1557dd7cddfSDavid du Colombier Strlen(m->type)+1 + Strlen(attr)+1 + 16 + ndata;
1567dd7cddfSDavid du Colombier buf = malloc(n+1); /* +1 for '\0' */
1577dd7cddfSDavid du Colombier if(buf == nil){
1587dd7cddfSDavid du Colombier free(attr);
1597dd7cddfSDavid du Colombier return nil;
1607dd7cddfSDavid du Colombier }
1617dd7cddfSDavid du Colombier p = Strcpy(buf, m->src);
1627dd7cddfSDavid du Colombier *p++ = '\n';
1637dd7cddfSDavid du Colombier p = Strcpy(p, m->dst);
1647dd7cddfSDavid du Colombier *p++ = '\n';
1657dd7cddfSDavid du Colombier p = Strcpy(p, m->wdir);
1667dd7cddfSDavid du Colombier *p++ = '\n';
1677dd7cddfSDavid du Colombier p = Strcpy(p, m->type);
1687dd7cddfSDavid du Colombier *p++ = '\n';
1697dd7cddfSDavid du Colombier p = Strcpy(p, attr);
1707dd7cddfSDavid du Colombier *p++ = '\n';
1717dd7cddfSDavid du Colombier p += sprint(p, "%d\n", ndata);
1727dd7cddfSDavid du Colombier memmove(p, m->data, ndata);
1737dd7cddfSDavid du Colombier *np = (p-buf)+ndata;
1747dd7cddfSDavid du Colombier buf[*np] = '\0'; /* null terminate just in case */
1757dd7cddfSDavid du Colombier if(*np >= n+1)
1767dd7cddfSDavid du Colombier abort();
1777dd7cddfSDavid du Colombier free(attr);
1787dd7cddfSDavid du Colombier return buf;
1797dd7cddfSDavid du Colombier }
1807dd7cddfSDavid du Colombier
1817dd7cddfSDavid du Colombier int
plumbsend(int fd,Plumbmsg * m)1827dd7cddfSDavid du Colombier plumbsend(int fd, Plumbmsg *m)
1837dd7cddfSDavid du Colombier {
1847dd7cddfSDavid du Colombier char *buf;
1857dd7cddfSDavid du Colombier int n;
1867dd7cddfSDavid du Colombier
1877dd7cddfSDavid du Colombier buf = plumbpack(m, &n);
1887dd7cddfSDavid du Colombier if(buf == nil)
1897dd7cddfSDavid du Colombier return -1;
1907dd7cddfSDavid du Colombier n = write(fd, buf, n);
1917dd7cddfSDavid du Colombier free(buf);
1927dd7cddfSDavid du Colombier return n;
1937dd7cddfSDavid du Colombier }
1947dd7cddfSDavid du Colombier
1957dd7cddfSDavid du Colombier static int
plumbline(char ** linep,char * buf,int i,int n,int * bad)1967dd7cddfSDavid du Colombier plumbline(char **linep, char *buf, int i, int n, int *bad)
1977dd7cddfSDavid du Colombier {
1987dd7cddfSDavid du Colombier int starti;
1997dd7cddfSDavid du Colombier char *p;
2007dd7cddfSDavid du Colombier
2017dd7cddfSDavid du Colombier starti = i;
2027dd7cddfSDavid du Colombier while(i<n && buf[i]!='\n')
2037dd7cddfSDavid du Colombier i++;
2047dd7cddfSDavid du Colombier if(i == n)
2057dd7cddfSDavid du Colombier *bad = 1;
2067dd7cddfSDavid du Colombier else{
2077dd7cddfSDavid du Colombier p = malloc((i-starti) + 1);
2087dd7cddfSDavid du Colombier if(p == nil)
2097dd7cddfSDavid du Colombier *bad = 1;
2107dd7cddfSDavid du Colombier else{
2117dd7cddfSDavid du Colombier memmove(p, buf+starti, i-starti);
2127dd7cddfSDavid du Colombier p[i-starti] = '\0';
2137dd7cddfSDavid du Colombier }
2147dd7cddfSDavid du Colombier *linep = p;
2157dd7cddfSDavid du Colombier i++;
2167dd7cddfSDavid du Colombier }
2177dd7cddfSDavid du Colombier return i;
2187dd7cddfSDavid du Colombier }
2197dd7cddfSDavid du Colombier
2207dd7cddfSDavid du Colombier void
plumbfree(Plumbmsg * m)2217dd7cddfSDavid du Colombier plumbfree(Plumbmsg *m)
2227dd7cddfSDavid du Colombier {
2237dd7cddfSDavid du Colombier Plumbattr *a, *next;
2247dd7cddfSDavid du Colombier
2257dd7cddfSDavid du Colombier free(m->src);
2267dd7cddfSDavid du Colombier free(m->dst);
2277dd7cddfSDavid du Colombier free(m->wdir);
2287dd7cddfSDavid du Colombier free(m->type);
2297dd7cddfSDavid du Colombier for(a=m->attr; a!=nil; a=next){
2307dd7cddfSDavid du Colombier next = a->next;
2317dd7cddfSDavid du Colombier free(a->name);
2327dd7cddfSDavid du Colombier free(a->value);
2337dd7cddfSDavid du Colombier free(a);
2347dd7cddfSDavid du Colombier }
2357dd7cddfSDavid du Colombier free(m->data);
2367dd7cddfSDavid du Colombier free(m);
2377dd7cddfSDavid du Colombier }
2387dd7cddfSDavid du Colombier
2397dd7cddfSDavid du Colombier Plumbattr*
plumbunpackattr(char * p)2407dd7cddfSDavid du Colombier plumbunpackattr(char *p)
2417dd7cddfSDavid du Colombier {
2427dd7cddfSDavid du Colombier Plumbattr *attr, *prev, *a;
243*9b7bf7dfSDavid du Colombier char *q, *v, *buf, *bufe;
2447dd7cddfSDavid du Colombier int c, quoting;
2457dd7cddfSDavid du Colombier
246*9b7bf7dfSDavid du Colombier buf = malloc(4096);
247*9b7bf7dfSDavid du Colombier if(buf == nil)
248*9b7bf7dfSDavid du Colombier return nil;
249*9b7bf7dfSDavid du Colombier bufe = buf + 4096;
2507dd7cddfSDavid du Colombier attr = prev = nil;
2517dd7cddfSDavid du Colombier while(*p!='\0' && *p!='\n'){
2527dd7cddfSDavid du Colombier while(*p==' ' || *p=='\t')
2537dd7cddfSDavid du Colombier p++;
2547dd7cddfSDavid du Colombier if(*p == '\0')
2557dd7cddfSDavid du Colombier break;
2567dd7cddfSDavid du Colombier for(q=p; *q!='\0' && *q!='\n' && *q!=' ' && *q!='\t'; q++)
2577dd7cddfSDavid du Colombier if(*q == '=')
2587dd7cddfSDavid du Colombier break;
2597dd7cddfSDavid du Colombier if(*q != '=')
2607dd7cddfSDavid du Colombier break; /* malformed attribute */
2617dd7cddfSDavid du Colombier a = malloc(sizeof(Plumbattr));
2627dd7cddfSDavid du Colombier if(a == nil)
2637dd7cddfSDavid du Colombier break;
2647dd7cddfSDavid du Colombier a->name = malloc(q-p+1);
2657dd7cddfSDavid du Colombier if(a->name == nil){
2667dd7cddfSDavid du Colombier free(a);
2677dd7cddfSDavid du Colombier break;
2687dd7cddfSDavid du Colombier }
2697dd7cddfSDavid du Colombier memmove(a->name, p, q-p);
2707dd7cddfSDavid du Colombier a->name[q-p] = '\0';
2717dd7cddfSDavid du Colombier /* process quotes in value */
2727dd7cddfSDavid du Colombier q++; /* skip '=' */
273*9b7bf7dfSDavid du Colombier v = buf;
2747dd7cddfSDavid du Colombier quoting = 0;
2757dd7cddfSDavid du Colombier while(*q!='\0' && *q!='\n'){
276*9b7bf7dfSDavid du Colombier if(v >= bufe)
2777dd7cddfSDavid du Colombier break;
2787dd7cddfSDavid du Colombier c = *q++;
2797dd7cddfSDavid du Colombier if(quoting){
2807dd7cddfSDavid du Colombier if(c == '\''){
2817dd7cddfSDavid du Colombier if(*q == '\'')
2827dd7cddfSDavid du Colombier q++;
2837dd7cddfSDavid du Colombier else{
2847dd7cddfSDavid du Colombier quoting = 0;
2857dd7cddfSDavid du Colombier continue;
2867dd7cddfSDavid du Colombier }
2877dd7cddfSDavid du Colombier }
2887dd7cddfSDavid du Colombier }else{
2897dd7cddfSDavid du Colombier if(c==' ' || c=='\t')
2907dd7cddfSDavid du Colombier break;
2917dd7cddfSDavid du Colombier if(c == '\''){
2927dd7cddfSDavid du Colombier quoting = 1;
2937dd7cddfSDavid du Colombier continue;
2947dd7cddfSDavid du Colombier }
2957dd7cddfSDavid du Colombier }
2967dd7cddfSDavid du Colombier *v++ = c;
2977dd7cddfSDavid du Colombier }
298*9b7bf7dfSDavid du Colombier a->value = malloc(v-buf+1);
2997dd7cddfSDavid du Colombier if(a->value == nil){
3007dd7cddfSDavid du Colombier free(a->name);
3017dd7cddfSDavid du Colombier free(a);
3027dd7cddfSDavid du Colombier break;
3037dd7cddfSDavid du Colombier }
304*9b7bf7dfSDavid du Colombier memmove(a->value, buf, v-buf);
305*9b7bf7dfSDavid du Colombier a->value[v-buf] = '\0';
3067dd7cddfSDavid du Colombier a->next = nil;
3077dd7cddfSDavid du Colombier if(prev == nil)
3087dd7cddfSDavid du Colombier attr = a;
3097dd7cddfSDavid du Colombier else
3107dd7cddfSDavid du Colombier prev->next = a;
3117dd7cddfSDavid du Colombier prev = a;
3127dd7cddfSDavid du Colombier p = q;
3137dd7cddfSDavid du Colombier }
314*9b7bf7dfSDavid du Colombier free(buf);
3157dd7cddfSDavid du Colombier return attr;
3167dd7cddfSDavid du Colombier }
3177dd7cddfSDavid du Colombier
3187dd7cddfSDavid du Colombier Plumbattr*
plumbaddattr(Plumbattr * attr,Plumbattr * new)3197dd7cddfSDavid du Colombier plumbaddattr(Plumbattr *attr, Plumbattr *new)
3207dd7cddfSDavid du Colombier {
3217dd7cddfSDavid du Colombier Plumbattr *l;
3227dd7cddfSDavid du Colombier
3237dd7cddfSDavid du Colombier l = attr;
3247dd7cddfSDavid du Colombier if(l == nil)
3257dd7cddfSDavid du Colombier return new;
3267dd7cddfSDavid du Colombier while(l->next != nil)
3277dd7cddfSDavid du Colombier l = l->next;
3287dd7cddfSDavid du Colombier l->next = new;
3297dd7cddfSDavid du Colombier return attr;
3307dd7cddfSDavid du Colombier }
3317dd7cddfSDavid du Colombier
3327dd7cddfSDavid du Colombier Plumbattr*
plumbdelattr(Plumbattr * attr,char * name)3337dd7cddfSDavid du Colombier plumbdelattr(Plumbattr *attr, char *name)
3347dd7cddfSDavid du Colombier {
3357dd7cddfSDavid du Colombier Plumbattr *l, *prev;
3367dd7cddfSDavid du Colombier
3377dd7cddfSDavid du Colombier prev = nil;
3387dd7cddfSDavid du Colombier for(l=attr; l!=nil; l=l->next){
3397dd7cddfSDavid du Colombier if(strcmp(name, l->name) == 0)
3407dd7cddfSDavid du Colombier break;
3417dd7cddfSDavid du Colombier prev = l;
3427dd7cddfSDavid du Colombier }
3437dd7cddfSDavid du Colombier if(l == nil)
3447dd7cddfSDavid du Colombier return nil;
3457dd7cddfSDavid du Colombier if(prev)
3467dd7cddfSDavid du Colombier prev->next = l->next;
3477dd7cddfSDavid du Colombier else
3487dd7cddfSDavid du Colombier attr = l->next;
3497dd7cddfSDavid du Colombier free(l->name);
3507dd7cddfSDavid du Colombier free(l->value);
3517dd7cddfSDavid du Colombier free(l);
3527dd7cddfSDavid du Colombier return attr;
3537dd7cddfSDavid du Colombier }
3547dd7cddfSDavid du Colombier
3557dd7cddfSDavid du Colombier Plumbmsg*
plumbunpackpartial(char * buf,int n,int * morep)3567dd7cddfSDavid du Colombier plumbunpackpartial(char *buf, int n, int *morep)
3577dd7cddfSDavid du Colombier {
3587dd7cddfSDavid du Colombier Plumbmsg *m;
3597dd7cddfSDavid du Colombier int i, bad;
3607dd7cddfSDavid du Colombier char *ntext, *attr;
3617dd7cddfSDavid du Colombier
3627dd7cddfSDavid du Colombier m = malloc(sizeof(Plumbmsg));
3637dd7cddfSDavid du Colombier if(m == nil)
3647dd7cddfSDavid du Colombier return nil;
3657dd7cddfSDavid du Colombier memset(m, 0, sizeof(Plumbmsg));
3667dd7cddfSDavid du Colombier if(morep != nil)
3677dd7cddfSDavid du Colombier *morep = 0;
3687dd7cddfSDavid du Colombier bad = 0;
3697dd7cddfSDavid du Colombier i = plumbline(&m->src, buf, 0, n, &bad);
3707dd7cddfSDavid du Colombier i = plumbline(&m->dst, buf, i, n, &bad);
3717dd7cddfSDavid du Colombier i = plumbline(&m->wdir, buf, i, n, &bad);
3727dd7cddfSDavid du Colombier i = plumbline(&m->type, buf, i, n, &bad);
3737dd7cddfSDavid du Colombier i = plumbline(&attr, buf, i, n, &bad);
37459cc4ca5SDavid du Colombier i = plumbline(&ntext, buf, i, n, &bad);
37559cc4ca5SDavid du Colombier if(bad){
37659cc4ca5SDavid du Colombier plumbfree(m);
37759cc4ca5SDavid du Colombier return nil;
37859cc4ca5SDavid du Colombier }
3797dd7cddfSDavid du Colombier m->attr = plumbunpackattr(attr);
3807dd7cddfSDavid du Colombier free(attr);
3817dd7cddfSDavid du Colombier m->ndata = atoi(ntext);
3827dd7cddfSDavid du Colombier if(m->ndata != n-i){
3837dd7cddfSDavid du Colombier bad = 1;
3847dd7cddfSDavid du Colombier if(morep!=nil && m->ndata>n-i)
3857dd7cddfSDavid du Colombier *morep = m->ndata - (n-i);
3867dd7cddfSDavid du Colombier }
3877dd7cddfSDavid du Colombier free(ntext);
3887dd7cddfSDavid du Colombier if(!bad){
3897dd7cddfSDavid du Colombier m->data = malloc(n-i+1); /* +1 for '\0' */
3907dd7cddfSDavid du Colombier if(m->data == nil)
3917dd7cddfSDavid du Colombier bad = 1;
3927dd7cddfSDavid du Colombier else{
3937dd7cddfSDavid du Colombier memmove(m->data, buf+i, m->ndata);
3947dd7cddfSDavid du Colombier m->ndata = n-i;
3957dd7cddfSDavid du Colombier /* null-terminate in case it's text */
3967dd7cddfSDavid du Colombier m->data[m->ndata] = '\0';
3977dd7cddfSDavid du Colombier }
3987dd7cddfSDavid du Colombier }
3997dd7cddfSDavid du Colombier if(bad){
4007dd7cddfSDavid du Colombier plumbfree(m);
4017dd7cddfSDavid du Colombier m = nil;
4027dd7cddfSDavid du Colombier }
4037dd7cddfSDavid du Colombier return m;
4047dd7cddfSDavid du Colombier }
4057dd7cddfSDavid du Colombier
4067dd7cddfSDavid du Colombier Plumbmsg*
plumbunpack(char * buf,int n)4077dd7cddfSDavid du Colombier plumbunpack(char *buf, int n)
4087dd7cddfSDavid du Colombier {
4097dd7cddfSDavid du Colombier return plumbunpackpartial(buf, n, nil);
4107dd7cddfSDavid du Colombier }
4117dd7cddfSDavid du Colombier
4127dd7cddfSDavid du Colombier Plumbmsg*
plumbrecv(int fd)4137dd7cddfSDavid du Colombier plumbrecv(int fd)
4147dd7cddfSDavid du Colombier {
4157dd7cddfSDavid du Colombier char *buf;
4167dd7cddfSDavid du Colombier Plumbmsg *m;
4177dd7cddfSDavid du Colombier int n, more;
4187dd7cddfSDavid du Colombier
4197dd7cddfSDavid du Colombier buf = malloc(8192);
4207dd7cddfSDavid du Colombier if(buf == nil)
4217dd7cddfSDavid du Colombier return nil;
4227dd7cddfSDavid du Colombier n = read(fd, buf, 8192);
4237dd7cddfSDavid du Colombier m = nil;
4247dd7cddfSDavid du Colombier if(n > 0){
4257dd7cddfSDavid du Colombier m = plumbunpackpartial(buf, n, &more);
4267dd7cddfSDavid du Colombier if(m==nil && more>0){
4277dd7cddfSDavid du Colombier /* we now know how many more bytes to read for complete message */
4287dd7cddfSDavid du Colombier buf = realloc(buf, n+more);
4297dd7cddfSDavid du Colombier if(buf == nil)
4307dd7cddfSDavid du Colombier return nil;
4317dd7cddfSDavid du Colombier if(readn(fd, buf+n, more) == more)
4327dd7cddfSDavid du Colombier m = plumbunpackpartial(buf, n+more, nil);
4337dd7cddfSDavid du Colombier }
4347dd7cddfSDavid du Colombier }
4357dd7cddfSDavid du Colombier free(buf);
4367dd7cddfSDavid du Colombier return m;
4377dd7cddfSDavid du Colombier }
438