17dd7cddfSDavid du Colombier #include <u.h> 27dd7cddfSDavid du Colombier #include <libc.h> 37dd7cddfSDavid du Colombier #include "plumb.h" 47dd7cddfSDavid du Colombier 57dd7cddfSDavid du Colombier static char attrbuf[4096]; 67dd7cddfSDavid du Colombier 77dd7cddfSDavid du Colombier int 87dd7cddfSDavid du Colombier plumbopen(char *name, int omode) 97dd7cddfSDavid du Colombier { 107dd7cddfSDavid du Colombier int fd, f; 11*9c06fe1dSDavid du Colombier char *s, *plumber; 12*9c06fe1dSDavid du Colombier char buf[128], err[ERRMAX]; 137dd7cddfSDavid du Colombier 147dd7cddfSDavid du Colombier if(name[0] == '/') 157dd7cddfSDavid du Colombier return open(name, omode); 16*9c06fe1dSDavid du Colombier 17*9c06fe1dSDavid du Colombier /* find elusive plumber */ 18*9c06fe1dSDavid du Colombier if(access("/mnt/plumb/send", OWRITE) >= 0) 19*9c06fe1dSDavid du Colombier plumber = "/mnt/plumb"; 20*9c06fe1dSDavid du Colombier else if(access("/mnt/term/mnt/plumb/send", OWRITE) >= 0) 21*9c06fe1dSDavid du Colombier plumber = "/mnt/term/mnt/plumb"; 22*9c06fe1dSDavid du Colombier else{ 23*9c06fe1dSDavid du Colombier /* last resort: try mounting service */ 24*9c06fe1dSDavid du Colombier plumber = "/mnt/plumb"; 257dd7cddfSDavid du Colombier s = getenv("plumbsrv"); 267dd7cddfSDavid du Colombier if(s == nil) 277dd7cddfSDavid du Colombier return -1; 287dd7cddfSDavid du Colombier f = open(s, ORDWR); 297dd7cddfSDavid du Colombier if(f < 0) 307dd7cddfSDavid du Colombier return -1; 31*9c06fe1dSDavid du Colombier if(mount(f, -1, "/mnt/plumb", MREPL, "") < 0){ 32*9c06fe1dSDavid du Colombier close(f); 337dd7cddfSDavid du Colombier return -1; 34*9c06fe1dSDavid du Colombier } 35*9c06fe1dSDavid du Colombier if(access("/mnt/plumb/send", OWRITE) < 0) 36*9c06fe1dSDavid du Colombier return -1; 37*9c06fe1dSDavid du Colombier } 38*9c06fe1dSDavid du Colombier 39*9c06fe1dSDavid du Colombier snprint(buf, sizeof buf, "%s/%s", plumber, name); 40*9c06fe1dSDavid du Colombier fd = open(buf, omode); 41*9c06fe1dSDavid du Colombier if(fd >= 0) 42*9c06fe1dSDavid du Colombier return fd; 43*9c06fe1dSDavid du Colombier 44*9c06fe1dSDavid du Colombier /* try creating port; used by non-standard plumb implementations */ 45*9c06fe1dSDavid du Colombier rerrstr(err, sizeof err); 46*9c06fe1dSDavid du Colombier fd = create(buf, omode, 0600); 47*9c06fe1dSDavid du Colombier if(fd >= 0) 48*9c06fe1dSDavid du Colombier return fd; 49*9c06fe1dSDavid du Colombier errstr(err, sizeof err); 50*9c06fe1dSDavid du Colombier 51*9c06fe1dSDavid du Colombier return -1; 527dd7cddfSDavid du Colombier } 537dd7cddfSDavid du Colombier 547dd7cddfSDavid du Colombier static int 557dd7cddfSDavid du Colombier Strlen(char *s) 567dd7cddfSDavid du Colombier { 577dd7cddfSDavid du Colombier if(s == nil) 587dd7cddfSDavid du Colombier return 0; 597dd7cddfSDavid du Colombier return strlen(s); 607dd7cddfSDavid du Colombier } 617dd7cddfSDavid du Colombier 627dd7cddfSDavid du Colombier static char* 637dd7cddfSDavid du Colombier Strcpy(char *s, char *t) 647dd7cddfSDavid du Colombier { 657dd7cddfSDavid du Colombier if(t == nil) 667dd7cddfSDavid du Colombier return s; 677dd7cddfSDavid du Colombier return strcpy(s, t) + strlen(t); 687dd7cddfSDavid du Colombier } 697dd7cddfSDavid du Colombier 707dd7cddfSDavid du Colombier /* quote attribute value, if necessary */ 717dd7cddfSDavid du Colombier static char* 727dd7cddfSDavid du Colombier quote(char *s) 737dd7cddfSDavid du Colombier { 747dd7cddfSDavid du Colombier char *t; 757dd7cddfSDavid du Colombier int c; 767dd7cddfSDavid du Colombier 777dd7cddfSDavid du Colombier if(s == nil){ 787dd7cddfSDavid du Colombier attrbuf[0] = '\0'; 797dd7cddfSDavid du Colombier return attrbuf; 807dd7cddfSDavid du Colombier } 817dd7cddfSDavid du Colombier if(strpbrk(s, " '=\t") == nil) 827dd7cddfSDavid du Colombier return s; 837dd7cddfSDavid du Colombier t = attrbuf; 847dd7cddfSDavid du Colombier *t++ = '\''; 857dd7cddfSDavid du Colombier while(t < attrbuf+sizeof attrbuf-2){ 867dd7cddfSDavid du Colombier c = *s++; 877dd7cddfSDavid du Colombier if(c == '\0') 887dd7cddfSDavid du Colombier break; 897dd7cddfSDavid du Colombier *t++ = c; 907dd7cddfSDavid du Colombier if(c == '\'') 917dd7cddfSDavid du Colombier *t++ = c; 927dd7cddfSDavid du Colombier } 937dd7cddfSDavid du Colombier *t++ = '\''; 947dd7cddfSDavid du Colombier *t = '\0'; 957dd7cddfSDavid du Colombier return attrbuf; 967dd7cddfSDavid du Colombier } 977dd7cddfSDavid du Colombier 987dd7cddfSDavid du Colombier char* 997dd7cddfSDavid du Colombier plumbpackattr(Plumbattr *attr) 1007dd7cddfSDavid du Colombier { 1017dd7cddfSDavid du Colombier int n; 1027dd7cddfSDavid du Colombier Plumbattr *a; 1037dd7cddfSDavid du Colombier char *s, *t; 1047dd7cddfSDavid du Colombier 1057dd7cddfSDavid du Colombier if(attr == nil) 1067dd7cddfSDavid du Colombier return nil; 1077dd7cddfSDavid du Colombier n = 0; 1087dd7cddfSDavid du Colombier for(a=attr; a!=nil; a=a->next) 1097dd7cddfSDavid du Colombier n += Strlen(a->name) + 1 + Strlen(quote(a->value)) + 1; 1107dd7cddfSDavid du Colombier s = malloc(n); 1117dd7cddfSDavid du Colombier if(s == nil) 1127dd7cddfSDavid du Colombier return nil; 1137dd7cddfSDavid du Colombier t = s; 1147dd7cddfSDavid du Colombier *t = '\0'; 1157dd7cddfSDavid du Colombier for(a=attr; a!=nil; a=a->next){ 1167dd7cddfSDavid du Colombier if(t != s) 1177dd7cddfSDavid du Colombier *t++ = ' '; 1187dd7cddfSDavid du Colombier strcpy(t, a->name); 1197dd7cddfSDavid du Colombier strcat(t, "="); 1207dd7cddfSDavid du Colombier strcat(t, quote(a->value)); 1217dd7cddfSDavid du Colombier t += strlen(t); 1227dd7cddfSDavid du Colombier } 1237dd7cddfSDavid du Colombier if(t > s+n) 1247dd7cddfSDavid du Colombier abort(); 1257dd7cddfSDavid du Colombier return s; 1267dd7cddfSDavid du Colombier } 1277dd7cddfSDavid du Colombier 1287dd7cddfSDavid du Colombier char* 1297dd7cddfSDavid du Colombier plumblookup(Plumbattr *attr, char *name) 1307dd7cddfSDavid du Colombier { 1317dd7cddfSDavid du Colombier while(attr){ 1327dd7cddfSDavid du Colombier if(strcmp(attr->name, name) == 0) 1337dd7cddfSDavid du Colombier return attr->value; 1347dd7cddfSDavid du Colombier attr = attr->next; 1357dd7cddfSDavid du Colombier } 1367dd7cddfSDavid du Colombier return nil; 1377dd7cddfSDavid du Colombier } 1387dd7cddfSDavid du Colombier 1397dd7cddfSDavid du Colombier char* 1407dd7cddfSDavid du Colombier plumbpack(Plumbmsg *m, int *np) 1417dd7cddfSDavid du Colombier { 1427dd7cddfSDavid du Colombier int n, ndata; 1437dd7cddfSDavid du Colombier char *buf, *p, *attr; 1447dd7cddfSDavid du Colombier 1457dd7cddfSDavid du Colombier ndata = m->ndata; 1467dd7cddfSDavid du Colombier if(ndata < 0) 1477dd7cddfSDavid du Colombier ndata = Strlen(m->data); 1487dd7cddfSDavid du Colombier attr = plumbpackattr(m->attr); 1497dd7cddfSDavid du Colombier n = Strlen(m->src)+1 + Strlen(m->dst)+1 + Strlen(m->wdir)+1 + 1507dd7cddfSDavid du Colombier Strlen(m->type)+1 + Strlen(attr)+1 + 16 + ndata; 1517dd7cddfSDavid du Colombier buf = malloc(n+1); /* +1 for '\0' */ 1527dd7cddfSDavid du Colombier if(buf == nil){ 1537dd7cddfSDavid du Colombier free(attr); 1547dd7cddfSDavid du Colombier return nil; 1557dd7cddfSDavid du Colombier } 1567dd7cddfSDavid du Colombier p = Strcpy(buf, m->src); 1577dd7cddfSDavid du Colombier *p++ = '\n'; 1587dd7cddfSDavid du Colombier p = Strcpy(p, m->dst); 1597dd7cddfSDavid du Colombier *p++ = '\n'; 1607dd7cddfSDavid du Colombier p = Strcpy(p, m->wdir); 1617dd7cddfSDavid du Colombier *p++ = '\n'; 1627dd7cddfSDavid du Colombier p = Strcpy(p, m->type); 1637dd7cddfSDavid du Colombier *p++ = '\n'; 1647dd7cddfSDavid du Colombier p = Strcpy(p, attr); 1657dd7cddfSDavid du Colombier *p++ = '\n'; 1667dd7cddfSDavid du Colombier p += sprint(p, "%d\n", ndata); 1677dd7cddfSDavid du Colombier memmove(p, m->data, ndata); 1687dd7cddfSDavid du Colombier *np = (p-buf)+ndata; 1697dd7cddfSDavid du Colombier buf[*np] = '\0'; /* null terminate just in case */ 1707dd7cddfSDavid du Colombier if(*np >= n+1) 1717dd7cddfSDavid du Colombier abort(); 1727dd7cddfSDavid du Colombier free(attr); 1737dd7cddfSDavid du Colombier return buf; 1747dd7cddfSDavid du Colombier } 1757dd7cddfSDavid du Colombier 1767dd7cddfSDavid du Colombier int 1777dd7cddfSDavid du Colombier plumbsend(int fd, Plumbmsg *m) 1787dd7cddfSDavid du Colombier { 1797dd7cddfSDavid du Colombier char *buf; 1807dd7cddfSDavid du Colombier int n; 1817dd7cddfSDavid du Colombier 1827dd7cddfSDavid du Colombier buf = plumbpack(m, &n); 1837dd7cddfSDavid du Colombier if(buf == nil) 1847dd7cddfSDavid du Colombier return -1; 1857dd7cddfSDavid du Colombier n = write(fd, buf, n); 1867dd7cddfSDavid du Colombier free(buf); 1877dd7cddfSDavid du Colombier return n; 1887dd7cddfSDavid du Colombier } 1897dd7cddfSDavid du Colombier 1907dd7cddfSDavid du Colombier static int 1917dd7cddfSDavid du Colombier plumbline(char **linep, char *buf, int i, int n, int *bad) 1927dd7cddfSDavid du Colombier { 1937dd7cddfSDavid du Colombier int starti; 1947dd7cddfSDavid du Colombier char *p; 1957dd7cddfSDavid du Colombier 1967dd7cddfSDavid du Colombier starti = i; 1977dd7cddfSDavid du Colombier while(i<n && buf[i]!='\n') 1987dd7cddfSDavid du Colombier i++; 1997dd7cddfSDavid du Colombier if(i == n) 2007dd7cddfSDavid du Colombier *bad = 1; 2017dd7cddfSDavid du Colombier else{ 2027dd7cddfSDavid du Colombier p = malloc((i-starti) + 1); 2037dd7cddfSDavid du Colombier if(p == nil) 2047dd7cddfSDavid du Colombier *bad = 1; 2057dd7cddfSDavid du Colombier else{ 2067dd7cddfSDavid du Colombier memmove(p, buf+starti, i-starti); 2077dd7cddfSDavid du Colombier p[i-starti] = '\0'; 2087dd7cddfSDavid du Colombier } 2097dd7cddfSDavid du Colombier *linep = p; 2107dd7cddfSDavid du Colombier i++; 2117dd7cddfSDavid du Colombier } 2127dd7cddfSDavid du Colombier return i; 2137dd7cddfSDavid du Colombier } 2147dd7cddfSDavid du Colombier 2157dd7cddfSDavid du Colombier void 2167dd7cddfSDavid du Colombier plumbfree(Plumbmsg *m) 2177dd7cddfSDavid du Colombier { 2187dd7cddfSDavid du Colombier Plumbattr *a, *next; 2197dd7cddfSDavid du Colombier 2207dd7cddfSDavid du Colombier free(m->src); 2217dd7cddfSDavid du Colombier free(m->dst); 2227dd7cddfSDavid du Colombier free(m->wdir); 2237dd7cddfSDavid du Colombier free(m->type); 2247dd7cddfSDavid du Colombier for(a=m->attr; a!=nil; a=next){ 2257dd7cddfSDavid du Colombier next = a->next; 2267dd7cddfSDavid du Colombier free(a->name); 2277dd7cddfSDavid du Colombier free(a->value); 2287dd7cddfSDavid du Colombier free(a); 2297dd7cddfSDavid du Colombier } 2307dd7cddfSDavid du Colombier free(m->data); 2317dd7cddfSDavid du Colombier free(m); 2327dd7cddfSDavid du Colombier } 2337dd7cddfSDavid du Colombier 2347dd7cddfSDavid du Colombier Plumbattr* 2357dd7cddfSDavid du Colombier plumbunpackattr(char *p) 2367dd7cddfSDavid du Colombier { 2377dd7cddfSDavid du Colombier Plumbattr *attr, *prev, *a; 2387dd7cddfSDavid du Colombier char *q, *v; 2397dd7cddfSDavid du Colombier int c, quoting; 2407dd7cddfSDavid du Colombier 2417dd7cddfSDavid du Colombier attr = prev = nil; 2427dd7cddfSDavid du Colombier while(*p!='\0' && *p!='\n'){ 2437dd7cddfSDavid du Colombier while(*p==' ' || *p=='\t') 2447dd7cddfSDavid du Colombier p++; 2457dd7cddfSDavid du Colombier if(*p == '\0') 2467dd7cddfSDavid du Colombier break; 2477dd7cddfSDavid du Colombier for(q=p; *q!='\0' && *q!='\n' && *q!=' ' && *q!='\t'; q++) 2487dd7cddfSDavid du Colombier if(*q == '=') 2497dd7cddfSDavid du Colombier break; 2507dd7cddfSDavid du Colombier if(*q != '=') 2517dd7cddfSDavid du Colombier break; /* malformed attribute */ 2527dd7cddfSDavid du Colombier a = malloc(sizeof(Plumbattr)); 2537dd7cddfSDavid du Colombier if(a == nil) 2547dd7cddfSDavid du Colombier break; 2557dd7cddfSDavid du Colombier a->name = malloc(q-p+1); 2567dd7cddfSDavid du Colombier if(a->name == nil){ 2577dd7cddfSDavid du Colombier free(a); 2587dd7cddfSDavid du Colombier break; 2597dd7cddfSDavid du Colombier } 2607dd7cddfSDavid du Colombier memmove(a->name, p, q-p); 2617dd7cddfSDavid du Colombier a->name[q-p] = '\0'; 2627dd7cddfSDavid du Colombier /* process quotes in value */ 2637dd7cddfSDavid du Colombier q++; /* skip '=' */ 2647dd7cddfSDavid du Colombier v = attrbuf; 2657dd7cddfSDavid du Colombier quoting = 0; 2667dd7cddfSDavid du Colombier while(*q!='\0' && *q!='\n'){ 2677dd7cddfSDavid du Colombier if(v >= attrbuf+sizeof attrbuf) 2687dd7cddfSDavid du Colombier break; 2697dd7cddfSDavid du Colombier c = *q++; 2707dd7cddfSDavid du Colombier if(quoting){ 2717dd7cddfSDavid du Colombier if(c == '\''){ 2727dd7cddfSDavid du Colombier if(*q == '\'') 2737dd7cddfSDavid du Colombier q++; 2747dd7cddfSDavid du Colombier else{ 2757dd7cddfSDavid du Colombier quoting = 0; 2767dd7cddfSDavid du Colombier continue; 2777dd7cddfSDavid du Colombier } 2787dd7cddfSDavid du Colombier } 2797dd7cddfSDavid du Colombier }else{ 2807dd7cddfSDavid du Colombier if(c==' ' || c=='\t') 2817dd7cddfSDavid du Colombier break; 2827dd7cddfSDavid du Colombier if(c == '\''){ 2837dd7cddfSDavid du Colombier quoting = 1; 2847dd7cddfSDavid du Colombier continue; 2857dd7cddfSDavid du Colombier } 2867dd7cddfSDavid du Colombier } 2877dd7cddfSDavid du Colombier *v++ = c; 2887dd7cddfSDavid du Colombier } 2897dd7cddfSDavid du Colombier a->value = malloc(v-attrbuf+1); 2907dd7cddfSDavid du Colombier if(a->value == nil){ 2917dd7cddfSDavid du Colombier free(a->name); 2927dd7cddfSDavid du Colombier free(a); 2937dd7cddfSDavid du Colombier break; 2947dd7cddfSDavid du Colombier } 2957dd7cddfSDavid du Colombier memmove(a->value, attrbuf, v-attrbuf); 2967dd7cddfSDavid du Colombier a->value[v-attrbuf] = '\0'; 2977dd7cddfSDavid du Colombier a->next = nil; 2987dd7cddfSDavid du Colombier if(prev == nil) 2997dd7cddfSDavid du Colombier attr = a; 3007dd7cddfSDavid du Colombier else 3017dd7cddfSDavid du Colombier prev->next = a; 3027dd7cddfSDavid du Colombier prev = a; 3037dd7cddfSDavid du Colombier p = q; 3047dd7cddfSDavid du Colombier } 3057dd7cddfSDavid du Colombier return attr; 3067dd7cddfSDavid du Colombier } 3077dd7cddfSDavid du Colombier 3087dd7cddfSDavid du Colombier Plumbattr* 3097dd7cddfSDavid du Colombier plumbaddattr(Plumbattr *attr, Plumbattr *new) 3107dd7cddfSDavid du Colombier { 3117dd7cddfSDavid du Colombier Plumbattr *l; 3127dd7cddfSDavid du Colombier 3137dd7cddfSDavid du Colombier l = attr; 3147dd7cddfSDavid du Colombier if(l == nil) 3157dd7cddfSDavid du Colombier return new; 3167dd7cddfSDavid du Colombier while(l->next != nil) 3177dd7cddfSDavid du Colombier l = l->next; 3187dd7cddfSDavid du Colombier l->next = new; 3197dd7cddfSDavid du Colombier return attr; 3207dd7cddfSDavid du Colombier } 3217dd7cddfSDavid du Colombier 3227dd7cddfSDavid du Colombier Plumbattr* 3237dd7cddfSDavid du Colombier plumbdelattr(Plumbattr *attr, char *name) 3247dd7cddfSDavid du Colombier { 3257dd7cddfSDavid du Colombier Plumbattr *l, *prev; 3267dd7cddfSDavid du Colombier 3277dd7cddfSDavid du Colombier prev = nil; 3287dd7cddfSDavid du Colombier for(l=attr; l!=nil; l=l->next){ 3297dd7cddfSDavid du Colombier if(strcmp(name, l->name) == 0) 3307dd7cddfSDavid du Colombier break; 3317dd7cddfSDavid du Colombier prev = l; 3327dd7cddfSDavid du Colombier } 3337dd7cddfSDavid du Colombier if(l == nil) 3347dd7cddfSDavid du Colombier return nil; 3357dd7cddfSDavid du Colombier if(prev) 3367dd7cddfSDavid du Colombier prev->next = l->next; 3377dd7cddfSDavid du Colombier else 3387dd7cddfSDavid du Colombier attr = l->next; 3397dd7cddfSDavid du Colombier free(l->name); 3407dd7cddfSDavid du Colombier free(l->value); 3417dd7cddfSDavid du Colombier free(l); 3427dd7cddfSDavid du Colombier return attr; 3437dd7cddfSDavid du Colombier } 3447dd7cddfSDavid du Colombier 3457dd7cddfSDavid du Colombier Plumbmsg* 3467dd7cddfSDavid du Colombier plumbunpackpartial(char *buf, int n, int *morep) 3477dd7cddfSDavid du Colombier { 3487dd7cddfSDavid du Colombier Plumbmsg *m; 3497dd7cddfSDavid du Colombier int i, bad; 3507dd7cddfSDavid du Colombier char *ntext, *attr; 3517dd7cddfSDavid du Colombier 3527dd7cddfSDavid du Colombier m = malloc(sizeof(Plumbmsg)); 3537dd7cddfSDavid du Colombier if(m == nil) 3547dd7cddfSDavid du Colombier return nil; 3557dd7cddfSDavid du Colombier memset(m, 0, sizeof(Plumbmsg)); 3567dd7cddfSDavid du Colombier if(morep != nil) 3577dd7cddfSDavid du Colombier *morep = 0; 3587dd7cddfSDavid du Colombier bad = 0; 3597dd7cddfSDavid du Colombier i = plumbline(&m->src, buf, 0, n, &bad); 3607dd7cddfSDavid du Colombier i = plumbline(&m->dst, buf, i, n, &bad); 3617dd7cddfSDavid du Colombier i = plumbline(&m->wdir, buf, i, n, &bad); 3627dd7cddfSDavid du Colombier i = plumbline(&m->type, buf, i, n, &bad); 3637dd7cddfSDavid du Colombier i = plumbline(&attr, buf, i, n, &bad); 36459cc4ca5SDavid du Colombier i = plumbline(&ntext, buf, i, n, &bad); 36559cc4ca5SDavid du Colombier if(bad){ 36659cc4ca5SDavid du Colombier plumbfree(m); 36759cc4ca5SDavid du Colombier return nil; 36859cc4ca5SDavid du Colombier } 3697dd7cddfSDavid du Colombier m->attr = plumbunpackattr(attr); 3707dd7cddfSDavid du Colombier free(attr); 3717dd7cddfSDavid du Colombier m->ndata = atoi(ntext); 3727dd7cddfSDavid du Colombier if(m->ndata != n-i){ 3737dd7cddfSDavid du Colombier bad = 1; 3747dd7cddfSDavid du Colombier if(morep!=nil && m->ndata>n-i) 3757dd7cddfSDavid du Colombier *morep = m->ndata - (n-i); 3767dd7cddfSDavid du Colombier } 3777dd7cddfSDavid du Colombier free(ntext); 3787dd7cddfSDavid du Colombier if(!bad){ 3797dd7cddfSDavid du Colombier m->data = malloc(n-i+1); /* +1 for '\0' */ 3807dd7cddfSDavid du Colombier if(m->data == nil) 3817dd7cddfSDavid du Colombier bad = 1; 3827dd7cddfSDavid du Colombier else{ 3837dd7cddfSDavid du Colombier memmove(m->data, buf+i, m->ndata); 3847dd7cddfSDavid du Colombier m->ndata = n-i; 3857dd7cddfSDavid du Colombier /* null-terminate in case it's text */ 3867dd7cddfSDavid du Colombier m->data[m->ndata] = '\0'; 3877dd7cddfSDavid du Colombier } 3887dd7cddfSDavid du Colombier } 3897dd7cddfSDavid du Colombier if(bad){ 3907dd7cddfSDavid du Colombier plumbfree(m); 3917dd7cddfSDavid du Colombier m = nil; 3927dd7cddfSDavid du Colombier } 3937dd7cddfSDavid du Colombier return m; 3947dd7cddfSDavid du Colombier } 3957dd7cddfSDavid du Colombier 3967dd7cddfSDavid du Colombier Plumbmsg* 3977dd7cddfSDavid du Colombier plumbunpack(char *buf, int n) 3987dd7cddfSDavid du Colombier { 3997dd7cddfSDavid du Colombier return plumbunpackpartial(buf, n, nil); 4007dd7cddfSDavid du Colombier } 4017dd7cddfSDavid du Colombier 4027dd7cddfSDavid du Colombier Plumbmsg* 4037dd7cddfSDavid du Colombier plumbrecv(int fd) 4047dd7cddfSDavid du Colombier { 4057dd7cddfSDavid du Colombier char *buf; 4067dd7cddfSDavid du Colombier Plumbmsg *m; 4077dd7cddfSDavid du Colombier int n, more; 4087dd7cddfSDavid du Colombier 4097dd7cddfSDavid du Colombier buf = malloc(8192); 4107dd7cddfSDavid du Colombier if(buf == nil) 4117dd7cddfSDavid du Colombier return nil; 4127dd7cddfSDavid du Colombier n = read(fd, buf, 8192); 4137dd7cddfSDavid du Colombier m = nil; 4147dd7cddfSDavid du Colombier if(n > 0){ 4157dd7cddfSDavid du Colombier m = plumbunpackpartial(buf, n, &more); 4167dd7cddfSDavid du Colombier if(m==nil && more>0){ 4177dd7cddfSDavid du Colombier /* we now know how many more bytes to read for complete message */ 4187dd7cddfSDavid du Colombier buf = realloc(buf, n+more); 4197dd7cddfSDavid du Colombier if(buf == nil) 4207dd7cddfSDavid du Colombier return nil; 4217dd7cddfSDavid du Colombier if(readn(fd, buf+n, more) == more) 4227dd7cddfSDavid du Colombier m = plumbunpackpartial(buf, n+more, nil); 4237dd7cddfSDavid du Colombier } 4247dd7cddfSDavid du Colombier } 4257dd7cddfSDavid du Colombier free(buf); 4267dd7cddfSDavid du Colombier return m; 4277dd7cddfSDavid du Colombier } 428