plumb.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <auth.h>
  4. #include <fcall.h>
  5. #include <thread.h>
  6. #include <plumb.h>
  7. #include <9p.h>
  8. #include "dat.h"
  9. #include "fns.h"
  10. static int plumbsendfd;
  11. static int plumbwebfd;
  12. static Channel *plumbchan;
  13. static void plumbwebproc(void*);
  14. static void plumbwebthread(void*);
  15. static void plumbsendproc(void*);
  16. void
  17. plumbinit(void)
  18. {
  19. plumbsendfd = plumbopen("send", OWRITE|OCEXEC);
  20. plumbwebfd = plumbopen("web", OREAD|OCEXEC);
  21. }
  22. void
  23. plumbstart(void)
  24. {
  25. plumbchan = chancreate(sizeof(Plumbmsg*), 0);
  26. proccreate(plumbwebproc, nil, STACK);
  27. threadcreate(plumbwebthread, nil, STACK);
  28. }
  29. static void
  30. plumbwebthread(void*)
  31. {
  32. char *base;
  33. Plumbmsg *m;
  34. for(;;){
  35. m = recvp(plumbchan);
  36. if(m == nil)
  37. threadexits(nil);
  38. base = plumblookup(m->attr, "baseurl");
  39. if(base == nil)
  40. base = m->wdir;
  41. plumburl(m->data, base);
  42. plumbfree(m);
  43. }
  44. }
  45. static void
  46. plumbwebproc(void*)
  47. {
  48. Plumbmsg *m;
  49. for(;;){
  50. m = plumbrecv(plumbwebfd);
  51. sendp(plumbchan, m);
  52. if(m == nil)
  53. threadexits(nil);
  54. }
  55. }
  56. static void
  57. addattr(Plumbmsg *m, char *name, char *value)
  58. {
  59. Plumbattr *a;
  60. a = malloc(sizeof(Plumbattr));
  61. a->name = name;
  62. a->value = value;
  63. a->next = m->attr;
  64. m->attr = a;
  65. }
  66. static void
  67. freeattrs(Plumbmsg *m)
  68. {
  69. Plumbattr *a, *next;
  70. a = m->attr;
  71. while(a != nil) {
  72. next = a->next;
  73. free(a);
  74. a = next;
  75. }
  76. }
  77. static struct
  78. {
  79. char *ctype;
  80. char *ext;
  81. }
  82. ctypes[] =
  83. {
  84. { "application/msword", "doc" },
  85. { "application/pdf", "pdf" },
  86. { "application/postscript", "ps" },
  87. { "application/rtf", "rtf" },
  88. { "image/gif", "gif" },
  89. { "image/jpeg", "jpg" },
  90. { "image/png", "png" },
  91. { "image/ppm", "ppm" },
  92. { "image/tiff", "tiff" },
  93. { "text/html", "html" },
  94. { "text/plain", "txt" },
  95. { "text/xml", "xml" },
  96. };
  97. void
  98. replumb(Client *c)
  99. {
  100. int i;
  101. Plumbmsg *m;
  102. char name[128], *ctype, *ext, *p;
  103. if(!c->plumbed)
  104. return;
  105. m = emalloc(sizeof(Plumbmsg));
  106. m->src = "webfs";
  107. m->dst = nil;
  108. m->wdir = "/";
  109. m->type = "text";
  110. m->attr = nil;
  111. addattr(m, "url", c->url->url);
  112. ctype = c->contenttype;
  113. ext = nil;
  114. if(ctype != nil) {
  115. addattr(m, "content-type", ctype);
  116. for(i = 0; i < nelem(ctypes); i++) {
  117. if(strcmp(ctype, ctypes[i].ctype) == 0) {
  118. ext = ctypes[i].ext;
  119. break;
  120. }
  121. }
  122. }
  123. if(ext == nil) {
  124. p = strrchr(c->url->url, '/');
  125. if(p != nil)
  126. p = strrchr(p+1, '.');
  127. if(p != nil && strlen(p) <= 5)
  128. ext = p+1;
  129. else
  130. ext = "txt"; /* punt */
  131. }
  132. c->ext = ext;
  133. if(0)fprint(2, "content type %s -> extension .%s\n", ctype, ext);
  134. m->ndata = snprint(name, sizeof name, "/mnt/web/%d/body.%s", c->num, ext);
  135. m->data = estrdup(name);
  136. proccreate(plumbsendproc, m, STACK); /* separate proc to avoid a deadlock */
  137. }
  138. static void
  139. plumbsendproc(void *x)
  140. {
  141. Plumbmsg *m;
  142. m = x;
  143. plumbsend(plumbsendfd, m);
  144. freeattrs(m);
  145. free(m->data);
  146. free(m);
  147. }