static clist * read_group_time_list(newsnntp * f) { char * line; char * group_name; time_t date; char * email; clist * group_time_list; struct newsnntp_group_time * n; int r; group_time_list = clist_new(); if (group_time_list == NULL) goto err; while (1) { char * p; char * remaining; line = read_line(f); if (line == NULL) goto free_list; if (mailstream_is_end_multiline(line)) break; p = cut_token(line); if (p == NULL) continue; date = strtoul(p, &remaining, 10); p = remaining; parse_space(&p); email = p; group_name = line; n = group_time_new(group_name, date, email); if (n == NULL) goto free_list; r = clist_append(group_time_list, n); if (r < 0) { group_time_free(n); goto free_list; } } return group_time_list; free_list: group_time_list_free(group_time_list); err: return NULL; }
static clist * read_distrib_default_value_list(newsnntp * f) { char * line; uint32_t weight; char * group_pattern; char * meaning; clist * distrib_default_value_list; struct newsnntp_distrib_default_value * n; int r; distrib_default_value_list = clist_new(); if (distrib_default_value_list == NULL) goto err; while (1) { char * p; char * remaining; line = read_line(f); if (line == NULL) goto free_list; if (mailstream_is_end_multiline(line)) break; p = line; weight = strtoul(p, &remaining, 10); p = remaining; parse_space(&p); p = cut_token(line); if (p == NULL) continue; meaning = p; group_pattern = line; n = distrib_default_value_new(weight, group_pattern, meaning); if (n == NULL) goto free_list; r = clist_append(distrib_default_value_list, n); if (r < 0) { distrib_default_value_free(n); goto free_list; } } return distrib_default_value_list; free_list: distrib_default_value_list_free(distrib_default_value_list); err: return NULL; }
static clist * read_group_description_list(newsnntp * f) { char * line; char * group_name; char * description; clist * group_description_list; struct newsnntp_group_description * n; int r; group_description_list = clist_new(); if (group_description_list == NULL) goto err; while (1) { char * p; line = read_line(f); if (line == NULL) goto free_list; if (mailstream_is_end_multiline(line)) break; p = cut_token(line); if (p == NULL) continue; description = p; group_name = line; n = group_description_new(group_name, description); if (n == NULL) goto free_list; r = clist_append(group_description_list, n); if (r < 0) { group_description_free(n); goto free_list; } } return group_description_list; free_list: group_description_list_free(group_description_list); err: return NULL; }
static clist * read_distrib_value_meaning_list(newsnntp * f) { char * line; char * value; char * meaning; clist * distrib_value_meaning_list; struct newsnntp_distrib_value_meaning * n; int r; distrib_value_meaning_list = clist_new(); if (distrib_value_meaning_list == NULL) goto err; while (1) { char * p; line = read_line(f); if (line == NULL) goto free_list; if (mailstream_is_end_multiline(line)) break; p = cut_token(line); if (p == NULL) continue; meaning = p; value = line; n = distrib_value_meaning_new(value, meaning); if (n == NULL) goto free_list; r = clist_append(distrib_value_meaning_list, n); if (r < 0) { distrib_value_meaning_free(n); goto free_list; } } return distrib_value_meaning_list; free_list: distrib_value_meaning_list_free(distrib_value_meaning_list); err: return NULL; }
// リクエストを送り、レスポンスを受け取る。戻り値はリターンコード。 int SakuraClient::request( const string& i_protocol, const string& i_protocol_version, const string& i_command, const strpairvec& i_data, string& o_protocol, string& o_protocol_version, strpairvec& o_data) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // リクエスト文字列を作成 string request = i_command + " " + i_protocol + "/" + i_protocol_version + CRLF; for ( strpairvec::const_iterator it = i_data.begin() ; it != i_data.end() ; ++it ) { request += it->first + ": " + it->second + CRLF; } request += CRLF; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // リクエスト実行 string response = this->request(request); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // お返事を解析 // 一行目を切り出し o_protocol = cut_token(response, "/"); o_protocol_version = cut_token(response, " "); int return_code = atoi( cut_token(response, " ").c_str() ); string return_string = cut_token(response, CRLF); // 以降のデータ行を切り出し while ( response.size() > 0 ) { string value = cut_token(response, CRLF); string key = cut_token(value, ": "); o_data.push_back( strpair(key, value) ); } return return_code; }
static int read_capa_resp(mailpop3 * f, clist ** result) { char * line; int res; clist * list; int r; char * name; clist * param_list; list = clist_new(); if (list == NULL) { res = MAILPOP3_NO_ERROR; goto err; } while (1) { char * next_token; char * param; struct mailpop3_capa * capa; line = read_line(f); if (line == NULL) { res = MAILPOP3_ERROR_STREAM; goto free_list; } if (mailstream_is_end_multiline(line)) break; next_token = cut_token(line); name = strdup(line); if (name == NULL) { res = MAILPOP3_ERROR_MEMORY; goto free_list; } param_list = clist_new(); if (param_list == NULL) { res = MAILPOP3_ERROR_MEMORY; goto free_capa_name; } while (next_token != NULL) { line = next_token; next_token = cut_token(line); param = strdup(line); if (param == NULL) { res = MAILPOP3_ERROR_MEMORY; goto free_param_list; } r = clist_append(param_list, param); if (r < 0) { free(param); res = MAILPOP3_ERROR_MEMORY; goto free_param_list; } } capa = mailpop3_capa_new(name, param_list); if (capa == NULL) { res = MAILPOP3_ERROR_MEMORY; goto free_param_list; } r = clist_append(list, capa); if (r < 0) { mailpop3_capa_free(capa); res = MAILPOP3_ERROR_MEMORY; goto free_list; } } * result = list; return MAILPOP3_NO_ERROR; free_param_list: clist_foreach(param_list, (clist_func) free, NULL); clist_free(param_list); free_capa_name: free(name); free_list: clist_foreach(list, (clist_func) mailpop3_capa_free, NULL); clist_free(list); err: return res; }
static clist * read_groups_list(newsnntp * f) { char * line; char * group_name; uint32_t first; uint32_t last; uint32_t count; int type; clist * groups_list; struct newsnntp_group_info * n; int r; groups_list = clist_new(); if (groups_list == NULL) goto err; while (1) { char * p; line = read_line(f); if (line == NULL) goto free_list; if (mailstream_is_end_multiline(line)) break; p = cut_token(line); if (p == NULL) continue; group_name = line; line = p; last = strtol(line, &line, 10); if (!parse_space(&line)) continue; first = strtol(line, &line, 10); if (!parse_space(&line)) continue; count = last - first + 1; type = * line; n = group_info_init(group_name, first, last, count, type); if (n == NULL) goto free_list; r = clist_append(groups_list, n); if (r < 0) { group_info_free(n); goto free_list; } } return groups_list; free_list: group_info_list_free(groups_list); err: return NULL; }
int begin_http_relay( SOCKET s ) { char buf[1024]; int result; char *auth_what; g_debug("begin_http_relay()\n"); if (sendf(s,"CONNECT %s:%d HTTP/1.0\r\n", dest_host, dest_port) < 0) return START_ERROR; if (proxy_auth_type == PROXY_AUTH_BASIC && basic_auth (s) < 0) return START_ERROR; if (sendf(s,"\r\n") < 0) return START_ERROR; if ( line_input(s, buf, sizeof(buf)) < 0 ) { g_debug("failed to read http response.\n"); return START_ERROR; } if (!strchr(buf, ' ')) { g_error ("Unexpected http response: '%s'.\n", buf); return START_ERROR; } result = atoi(strchr(buf,' ')); switch ( result ) { case 200: g_debug("connected, start user session.\n"); break; case 302: do { if (line_input(s, buf, sizeof(buf))) break; downcase(buf); if (expect(buf, "Location: ")) { relay_host = cut_token(buf, "//"); cut_token(buf, "/"); relay_port = atoi(cut_token(buf, ":")); } } while (strcmp(buf,"\r\n") != 0); return START_RETRY; case 401: case 407: /*TODO - authentication*/ if (proxy_auth_type != PROXY_AUTH_NONE) { g_error("Authentication failed.\n"); return START_ERROR; } auth_what = (result == 401) ? "WWW-Authenticate:" : "Proxy-Authenticate:"; do { if ( line_input(s, buf, sizeof(buf)) ) { break; } downcase(buf); if (expect(buf, auth_what)) { char *scheme, *realm; scheme = cut_token(buf, " "); realm = cut_token(scheme, " "); if ( scheme == NULL || realm == NULL ) { g_debug("Invalid format of %s field.", auth_what); return START_ERROR; } if (expect(scheme, "basic")) { proxy_auth_type = PROXY_AUTH_BASIC; } else { g_debug("Unsupported authentication type: %s", scheme); } } } while (strcmp(buf,"\r\n") != 0); if ( proxy_auth_type == PROXY_AUTH_NONE ) { g_debug("Can't find %s in response header.", auth_what); return START_ERROR; } else { return START_RETRY; } default: g_debug("http proxy is not allowed.\n"); return START_ERROR; } do { if ( line_input(s, buf, sizeof(buf) ) ) { g_debug("Can't skip response headers\n"); return START_ERROR; } } while ( strcmp(buf,"\r\n") != 0 ); return START_OK; }
string SakuraDLLHost::request(const string& i_request_string) { //GetSender().sender() << "--- Request ---" << endl << i_request_string << endl; // HTTPもどき形式の要求文字列を解析する // restには未解釈の「残り」が入っている string rest = i_request_string; // 一行目を切り出し string command = cut_token(rest, CRLF); // 後ろから ' ' を探し、見つかればそれ以降をプロトコル部分として認識する string protocol, protocol_version; for ( int n = command.size()-1 ; n >= 0 ; --n ) { if ( command[n] == ' ' ) { protocol_version = command.substr(n+1); // いったん全部を預けて…… protocol = cut_token(protocol_version, "/"); // /より前を取り出す。 /が無ければ全部貰い受ける command = command.substr(0, n); break; } } // 以降のデータ行を切り出し strpairvec data; while ( rest.size() > 0 ) { string value = cut_token(rest, CRLF); string key = cut_token(value, ": "); data.push_back( strpair(key, value) ); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // リクエストを実行する // 戻り値格納用オブジェクト string r_protocol, r_protocol_version; strpairvec r_data; int r_return_code = request( protocol, protocol_version, command, data, r_protocol, r_protocol_version, r_data); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 返答をHTTPもどき文字列形式として構築し、返す。 string response; response += r_protocol + "/" + r_protocol_version + " "; switch ( r_return_code ) { case 200: response += "200 OK"; break; case 204: response += "204 No Content"; break; case 400: response += "400 Bad Request"; break; default: response += "500 Internal Server Error"; break; } response += CRLF; // Charsetが無ければ付ける。 bool charset_exists = false; for (strpairvec::const_iterator ite = r_data.begin(); ite != r_data.end(); ite++) { if (ite->first == "Charset") { charset_exists = true; break; } } if (!charset_exists) { r_data.push_back(strpair("Charset", "Shift_JIS")); } for ( strpairvec::const_iterator i = r_data.begin() ; i != r_data.end() ; ++i ) { response += i->first + ": " + i->second + CRLF; } response += CRLF; //GetSender().sender() << "--- Response ---" << endl << response << endl; return response; }
string cut_token(string& io_target, const string& i_delimiter) { string word; cut_token(io_target, i_delimiter, word); return word; }