void xioclose(int fd) { Ioproc *io; if((io = xioproc()) == nil){ close(fd); return; } ioclose(io, fd); closexioproc(io); }
void httpclose(Client *c) { HttpState *hs; hs = c->aux; if(hs == nil) return; if(hs->fd >= 0) ioclose(c->io, hs->fd); hs->fd = -1; free(hs->location); free(hs->setcookie); free(hs->netaddr); free(hs->credentials); free(hs); c->aux = nil; }
BoolType init_kanamap(const char *libdir, const char *key_type) { FILEsIO *fp; unsigned char buf[KMAXLEN]; int i, cc; kanachar k0, kv; static int alreadyused = 0; StrType mapfile; if (alreadyused) return TRUE; for (i = 0; i < 256; i++) kanamap[i] = kchars[s_sp]; if (isHttp) { sprintf(mapfile, "%s/%s.map", libdir, key_type); fp = open_url(mapfile); }else { sprintf(mapfile, "%s%c%s.map", libdir, DELIM, key_type); fp = makeFilesio( fopen(mapfile, "r") ); } if (fp == NULL) return FALSE; while (iogets((char *)buf, KMAXLEN, fp) != NULL) { if ((cc = buf[0]) <= ' ') continue; for (i = 1; buf[i] == ' ' || buf[i] == '\t'; i++) ; k0 = buf[i++] & 0xff; kv = (k0 << 8) | (buf[i++] & 0xff); #if (KANA_CODE == UTF_8) if (k0 >= 0xe0) { kv = (kv << 8) | (buf[i++] & 0xff); if (k0 > 0xef) kv = (kv << 8) | (buf[i++] & 0xff); } #endif kanamap[cc] = kv; } alreadyused = 1; ioclose(fp); return TRUE; }
BoolType find_lesson(const char *name) /* locate given lesson, leave lesson_file open so next line begins */ { StrType fullName; StrType current_line; char slash; FILEsIO *lesson_file; size_t linesInLesson; int idx, lng, kind; if ((idx = check_lesson_name(name)) < 0) { stand_out(BOLD); #ifdef JPN add_fmt("\n \"%s\" というレッスンはありません.\n", name); #else add_fmt("\n %s: No such Lesson.\n", name); #endif stand_end(BOLD); (void) wait_user(); return FALSE; } /* gf: Added LessonDir */ slash = isHttp ? '/' : DELIM; if (typeLessons[idx].path == NULL) sprintf(fullName, "%s%c%c.typ", LessonDir, slash, name[0]); else sprintf(fullName, "%s%c%s.typ", LessonDir, slash, typeLessons[idx].path); lesson_file = isHttp ? open_url(fullName) : makeFilesio( fopen(fullName, "r") ); if (lesson_file == NULL) { stand_out(BOLD); add_fmt("OPEN ERROR: %s (errno=%d)\n", fullName, errno); stand_end(BOLD); (void) wait_user(); return FALSE; } if (!seek_lesson(lesson_file, name)) goto ERR_EXIT; /* clear previous lesson */ clear_dictionary(); clear_cache(); linesInLesson = 0; while ((lng = get_lesson_line(lesson_file, current_line)) >= 0) { /* Loop ends if EOF or End of Lesson */ kind = 0; if (lng >= 2 && current_line[lng - 2] == '\\') { /* expected terminator */ kind = current_line[lng - 1]; current_line[lng -= 2] = '\0'; /* remove */ } if (lng == 0) cached_lines[linesInLesson] = empty; else { char *pp = (char *)malloc(lng + 1); if (pp == NULL) { fprintf(stderr, "SYSTEM ERROR: malloc() failure\n"); cleanup(1); } strcpy(pp, current_line); cached_lines[linesInLesson] = pp; } cached_attr[linesInLesson] = kind; if (++linesInLesson >= cacheCapacity - 1) increse_cache(); } /* The next of the last line, cached_lines[linesInLesson] should be NULL */ ioclose(lesson_file); return TRUE; ERR_EXIT: stand_out(BOLD); #ifdef JPN add_fmt("レッスン%s は利用できません.\n", &name[1]); #else add_fmt("Lesson %s is not available.\n", &name[1]); #endif stand_end(BOLD); (void) wait_user(); ioclose(lesson_file); return FALSE; }
int httpopen(Client *c, Url *url) { int fd, code, redirect, authenticate; char *cookies; Ioproc *io; HttpState *hs; char *service; if(httpdebug) fprint(2, "httpopen\n"); io = c->io; hs = emalloc(sizeof(*hs)); hs->c = c; if(url->port) service = url->port; else service = url->scheme; hs->netaddr = estrdup(netmkaddr(url->host, 0, service)); c->aux = hs; if(httpdebug){ fprint(2, "dial %s\n", hs->netaddr); fprint(2, "dial port: %s\n", url->port); } fd = iotlsdial(io, hs->netaddr, 0, 0, 0, url->ischeme==UShttps); if(fd < 0){ Error: if(httpdebug) fprint(2, "iodial: %r\n"); free(hs->location); free(hs->setcookie); free(hs->netaddr); free(hs->credentials); if(fd >= 0) ioclose(io, hs->fd); hs->fd = -1; free(hs); c->aux = nil; return -1; } hs->fd = fd; if(httpdebug) fprint(2, "<- %s %s HTTP/1.0\n<- Host: %s\n", c->havepostbody? "POST": "GET", url->http.page_spec, url->host); ioprint(io, fd, "%s %s HTTP/1.0\r\nHost: %s\r\n", c->havepostbody? "POST" : "GET", url->http.page_spec, url->host); if(httpdebug) fprint(2, "<- User-Agent: %s\n", c->ctl.useragent); if(c->ctl.useragent) ioprint(io, fd, "User-Agent: %s\r\n", c->ctl.useragent); if(c->ctl.sendcookies){ /* should we use url->page here? sometimes it is nil. */ cookies = httpcookies(url->host, url->http.page_spec, url->ischeme == UShttps); if(cookies && cookies[0]) ioprint(io, fd, "%s", cookies); if(httpdebug) fprint(2, "<- %s", cookies); free(cookies); } if(c->havepostbody){ ioprint(io, fd, "Content-type: %s\r\n", PostContentType); ioprint(io, fd, "Content-length: %ud\r\n", c->npostbody); if(httpdebug){ fprint(2, "<- Content-type: %s\n", PostContentType); fprint(2, "<- Content-length: %ud\n", c->npostbody); } } if(c->authenticate){ ioprint(io, fd, "Authorization: %s\r\n", c->authenticate); if(httpdebug) fprint(2, "<- Authorization: %s\n", c->authenticate); } ioprint(io, fd, "\r\n"); if(c->havepostbody) if(iowrite(io, fd, c->postbody, c->npostbody) != c->npostbody) goto Error; redirect = 0; authenticate = 0; initibuf(&hs->b, io, fd); code = httprcode(hs); switch(code){ case -1: /* connection timed out */ goto Error; /* case Eof: werrstr("EOF from HTTP server"); goto Error; */ case 200: /* OK */ case 201: /* Created */ case 202: /* Accepted */ case 204: /* No Content */ case 205: /* Reset Content */ #ifdef NOT_DEFINED if(ofile == nil && r->start != 0) sysfatal("page changed underfoot"); #endif break; case 206: /* Partial Content */ werrstr("Partial Content (206)"); goto Error; case 301: /* Moved Permanently */ case 302: /* Moved Temporarily */ case 303: /* See Other */ case 307: /* Temporary Redirect */ redirect = 1; break; case 304: /* Not Modified */ break; case 400: /* Bad Request */ werrstr("Bad Request (400)"); goto Error; case 401: /* Unauthorized */ if(c->authenticate){ werrstr("Authentication failed (401)"); goto Error; } authenticate = 1; break; case 402: /* Payment Required */ werrstr("Payment Required (402)"); goto Error; case 403: /* Forbidden */ werrstr("Forbidden by server (403)"); goto Error; case 404: /* Not Found */ werrstr("Not found on server (404)"); goto Error; case 405: /* Method Not Allowed */ werrstr("Method not allowed (405)"); goto Error; case 406: /* Not Acceptable */ werrstr("Not Acceptable (406)"); goto Error; case 407: /* Proxy auth */ werrstr("Proxy authentication required (407)"); goto Error; case 408: /* Request Timeout */ werrstr("Request Timeout (408)"); goto Error; case 409: /* Conflict */ werrstr("Conflict (409)"); goto Error; case 410: /* Gone */ werrstr("Gone (410)"); goto Error; case 411: /* Length Required */ werrstr("Length Required (411)"); goto Error; case 412: /* Precondition Failed */ werrstr("Precondition Failed (412)"); goto Error; case 413: /* Request Entity Too Large */ werrstr("Request Entity Too Large (413)"); goto Error; case 414: /* Request-URI Too Long */ werrstr("Request-URI Too Long (414)"); goto Error; case 415: /* Unsupported Media Type */ werrstr("Unsupported Media Type (415)"); goto Error; case 416: /* Requested Range Not Satisfiable */ werrstr("Requested Range Not Satisfiable (416)"); goto Error; case 417: /* Expectation Failed */ werrstr("Expectation Failed (417)"); goto Error; case 500: /* Internal server error */ werrstr("Server choked (500)"); goto Error; case 501: /* Not implemented */ werrstr("Server can't do it (501)"); goto Error; case 502: /* Bad gateway */ werrstr("Bad gateway (502)"); goto Error; case 503: /* Service unavailable */ werrstr("Service unavailable (503)"); goto Error; default: /* Bogus: we should treat unknown code XYZ as code X00 */ werrstr("Unknown response code %d", code); goto Error; } if(httpheaders(hs) < 0) goto Error; if(c->ctl.acceptcookies && hs->setcookie) httpsetcookie(hs->setcookie, url->host, url->path); if(authenticate){ if(!hs->credentials){ if(hs->autherror[0]) werrstr("%s", hs->autherror); else werrstr("unauthorized; no www-authenticate: header"); goto Error; } c->authenticate = hs->credentials; hs->credentials = nil; }else if(c->authenticate) c->authenticate = 0; if(redirect){ if(!hs->location){ werrstr("redirection without Location: header"); goto Error; } c->redirect = hs->location; hs->location = nil; } return 0; }
static void iodestroy(void* f) { if(f != stdin && f != stdout && f != stderr) ioclose(0, f); }