16 urlalloc(Runestr *src, Runestr *post, int m)
20 u = emalloc(sizeof(Url));
21 copyrunestr(&u->src, src);
23 copyrunestr(&u->post, post);
32 if(u==nil || decref(u) > 0)
35 closerunestr(&u->src);
36 closerunestr(&u->act);
37 closerunestr(&u->post);
38 closerunestr(&u->ctype);
47 b = emalloc(sizeof(Url));
48 b->method = a->method;
49 copyrunestr(&b->src, &a->src);
50 copyrunestr(&b->act, &a->act);
51 copyrunestr(&b->post, &a->post);
52 copyrunestr(&b->ctype, &a->ctype);
57 getattr(int conn, char *s)
63 snprint(buf, sizeof buf, "%s/%d/%s", webmountpt, conn, s);
64 if((fd = open(buf, OREAD)) >= 0){
65 if((n = read(fd, buf, sizeof(buf)-1)) < 0)
70 return (Runestr){runesmprint("%s", buf), n};
73 // tired of typing http://, tired of going to google first.
81 u->src.r = runesmprint("http://www.google.com/search?hl=en&ie=UTF-8&q=%S", s);
83 u->src.nr = runestrlen(u->src.r);
90 if(validurl(u->src.r))
93 u->src.r = runesmprint("http://%S", u->src.r);
95 u->src.nr = runestrlen(u->src.r);
103 justgoogleit, L"g ", 2,
112 for(i = 0; u->src.nr >= ctab[i].len && runestrncmp(u->src.r, ctab[i].lead, ctab[i].len) != 0; i++)
121 int cfd, fd, conn, n;
124 snprint(buf, sizeof(buf), "%s/clone", webmountpt);
125 cfd = open(buf, ORDWR);
127 error("can't open clone file");
129 n = read(cfd, buf, sizeof(buf)-1);
131 error("reading clone");
136 snprint(buf, sizeof(buf), "url %S", u->src.r);
137 if(write(cfd, buf, strlen(buf)) < 0){
138 // fprint(2, "write: %s: %r\n", buf);
143 if(u->method==HPost && u->post.r != nil){
144 snprint(buf, sizeof(buf), "%s/%d/postbody", webmountpt, conn);
145 fd = open(buf, OWRITE);
147 // fprint(2, "urlopen: bad query: %s: %r\n", buf);
150 snprint(buf, sizeof(buf), "%S", u->post.r);
151 if(write(fd, buf, strlen(buf)) < 0)
152 fprint(2, "urlopen: bad query: %s: %r\n", buf);
156 snprint(buf, sizeof(buf), "%s/%d/body", webmountpt, conn);
157 fd = open(buf, OREAD);
159 // fprint(2, "open: %S: %r\n", u->src.r);
162 u->ctype = getattr(conn, "contenttype");
163 u->act = getattr(conn, "parsed/url");
165 copyrunestr(&u->act, &u->src);
173 Rune *s, *e, *tail, tailr;
174 Rune **comp, **p, **q;
177 name = runestrstr(name, L"://");
180 name = runestrchr(name+3, '/');
187 for(e = name; *e != 0; e++)
190 comp = emalloc((n+2)*sizeof *comp);
193 * Break the name into a list of components
198 tailr = L'☺'; /* silence compiler */
199 for(s = name; *s != 0; s++){
200 if(*s == '?' || *s == '#'){
213 * go through the component list, deleting components that are empty (except
214 * the last component) or ., and any .. and its predecessor.
216 for(p = q = comp; *p != nil; p++){
217 if(runestrcmp(*p, L"") == 0 && p[1] != nil
218 || runestrcmp(*p, L".") == 0)
220 else if(q>comp && runestrcmp(*p, L"..") == 0 && runestrcmp(q[-1], L"..") != 0)
228 * rebuild the path name
231 for(p = comp; p<q; p++){
233 memmove(s, *p, sizeof(Rune)*n);
240 runeseprint(s, e+1, "%C%S", tailr, tail);
246 urlcombine(Rune *b, Rune *u)
248 Rune *p, *q, *sep, *s;
249 Rune endrune[] = { L'?', L'#' };
253 error("urlcombine: u == nil");
256 return erunestrdup(u);
258 if(b==nil || !validurl(b))
259 error("urlcombine: b==nil || !validurl(b)");
261 if(runestrncmp(u, L"//", 2) == 0){
262 q = runestrchr(b, L':');
263 return runesmprint("%.*S:%S", (int)(q-b), b, u);
265 p = runestrstr(b, L"://");
271 q = runestrchr(p, L'/');
272 else if(*u==L'#' || *u==L'?'){
273 for(i=0; i<nelem(endrune); i++)
274 if(q = runestrchr(p, endrune[i]))
279 s = runestrchr(p, L'?');
284 q = runestrrchr(p, L'/');
290 p = runesmprint("%S%S%S", b, sep, u);
292 p = runesmprint("%.*S%S%S", (int)(q-b), b, sep, u);