static void scan_msgbase(int num) { int i, first = -1; char *headers; if (!changemsgbase(num, MC_QUICK | MC_NOSTAT)) return; getmsgptrs(); if (!(headers = get_headers())) return; for (i = lowest; i <= highest; i++) { if (!headers[i - lowest]) continue; if (!simple_search(i)) headers[i - lowest] = 0; else if (first == -1) first = i; } if (first == -1) return; readmessages(-1, first, headers); free(headers); }
int manage_ncp(void * packiet_data,uint16_t packiet_len ) { int i = 0; ethernet_header* eh; ip_header * ip; udp_header * udp; ncp_header * ncp; uint16_t data_size; get_headers(packiet_data,&eh,&ip,&udp,&ncp); data_size = udp->uh_ulen; switch (current_state) { case START: ncp_register(&m_ncp,NCP_HEADER_SIZE); output_size = create_packiet(output_packiet,ETHER_MAX_LEN,m_ncp,NCP_HEADER_SIZE); TransmitPacket(output_packiet,output_size); next_state = IDLE; break; case IDLE: if(packiet_len=0) break; if(ncp->ncp_comm == NCP_DATA) { i = memcmp(&(ncp->ncp_client),get_host_uuid(),sizeof(uuid)); if(i == 0) next_state = PROCESSING ; } else return 0; break; // wait for processing order case PROCESSING: outcome_size = process_ncp(ncp,data_size,outcome_ncp,ETHER_MAX_LEN); printf("PROCESSING \n"); next_state = RESULT; break; case RESULT: ncp_result(&m_ncp,NCP_HEADER_SIZE,0,0); output_size = create_packiet(output_packiet,ETHER_MAX_LEN,&m_ncp,outcome_size); TransmitPacket(output_packiet,output_size); next_state = IDLE; break; case MAX_STATE: printf ("Manage Ncp: unpredicted state\n"); break; default: printf ("Manage Ncp: unknow state\n"); }; current_state = next_state; return 0; }
/** * Send the response to the client. If the response has already been * commited, this function does nothing. */ static void send_response(HttpResponse res) { Socket_T S= res->S; if(!res->is_committed) { char date[STRLEN]; char server[STRLEN]; char *headers= get_headers(res); int length = StringBuffer_length(res->outputbuffer); res->is_committed= TRUE; get_date(date, STRLEN); get_server(server, STRLEN); socket_print(S, "%s %d %s\r\n", res->protocol, res->status, res->status_msg); socket_print(S, "Date: %s\r\n", date); socket_print(S, "Server: %s\r\n", server); socket_print(S, "Content-Length: %d\r\n", length); socket_print(S, "Connection: close\r\n"); if(headers) socket_print(S, "%s", headers); socket_print(S, "\r\n"); if(length) socket_write(S, (unsigned char *)StringBuffer_toString(res->outputbuffer), length); FREE(headers); } }
static char *unarchive(struct gzip_handle *src_stream, FILE * out_stream, file_header_t * (*get_headers) (struct gzip_handle *), void (*free_headers) (file_header_t *), const int extract_function, const char *prefix, const char **extract_names, int *err) { file_header_t *file_entry; int extract_flag; int i; char *buffer = NULL; *err = 0; archive_offset = 0; while ((file_entry = get_headers(src_stream)) != NULL) { extract_flag = TRUE; if (extract_names != NULL) { int found_flag = FALSE; char *p = file_entry->name; if (p[0] == '.' && p[1] == '/') p += 2; for (i = 0; extract_names[i] != 0; i++) { if (strcmp(extract_names[i], p) == 0) { found_flag = TRUE; break; } } if (extract_function & extract_exclude_list) { if (found_flag == TRUE) { extract_flag = FALSE; } } else { /* If its not found in the include list dont extract it */ if (found_flag == FALSE) { extract_flag = FALSE; } } } if (extract_flag == TRUE) { buffer = extract_archive(src_stream, out_stream, file_entry, extract_function, prefix, err); *err = 0; /* XXX: ignore extraction errors */ if (*err) { free_headers(file_entry); break; } } else { /* seek past the data entry */ seek_forward(src_stream, file_entry->size); } free_headers(file_entry); } return buffer; }
Array HHVM_FUNCTION(apache_request_headers) { Transport *transport = g_context->getTransport(); if (transport) { HeaderMap headers; transport->getHeaders(headers); return get_headers(headers); } return Array(); }
Array HHVM_FUNCTION(apache_response_headers) { Transport *transport = g_context->getTransport(); if (transport) { HeaderMap headers; transport->getResponseHeaders(headers); return get_headers(headers); } return empty_array(); }
Array HHVM_FUNCTION(get_headers_secure) { Transport *transport = g_context->getTransport(); if (transport) { HeaderMap headers; transport->getHeaders(headers); return get_headers(headers, true); } return empty_array(); }
/** * @brief HTTP::download * @return int */ int HTTP::download() { initiateConnection(); // connection init send_request(); // send request with headers get_headers(); // get headers, find if chunked, redirection etc. std::string s = get_content(); // save the content std::ofstream out("output.xml"); out << s; // save to file out.close(); return 0; }
static CURL* curl_request(lua_State* L, CurlCallbackState* state, FILE* fp, int progressFnIndex) { CURL* curl; struct curl_slist* headers = NULL; const char* url = luaL_checkstring(L, 1); /* if the second argument is a lua function, then we save it to call it later as the http progress callback */ if (lua_type(L, progressFnIndex) == LUA_TFUNCTION) { state->L = L; state->RefIndex = luaL_ref(L, LUA_REGISTRYINDEX); } curl_init(); curl = curl_easy_init(); if (!curl) return NULL; curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, state->errorBuffer); get_headers(L, &headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_WRITEDATA, state); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_cb); if (fp) { curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_file_cb); } if (state->L != 0) { curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, state); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, curl_progress_cb); } // clear error buffer. state->errorBuffer[0] = 0; return curl; }
/** * This callback does things a bit differently. * Instead of using a MultiResult, we use a single HttpResult object. * We won't ever have "multiple" http objects. */ static void http_complete_callback(lcb_http_request_t req, lcb_t instance, const void *cookie, lcb_error_t err, const lcb_http_resp_t *resp) { pycbc_HttpResult *htres = (pycbc_HttpResult*)cookie; htres->htreq = NULL; htres->rc = err; htres->htcode = resp->v.v0.status; htres->htflags |= PYCBC_HTRES_F_COMPLETE; if (!htres->parent) { return; } PYCBC_CONN_THR_END(htres->parent); add_data(htres, resp->v.v0.bytes, resp->v.v0.nbytes); get_headers(htres, resp); finalize_data(htres); PYCBC_CONN_THR_BEGIN(htres->parent); if (htres->htflags & PYCBC_HTRES_F_CHUNKED) { /** No data here */ if (!htres->parent->nremaining) { lcb_breakout(instance); } maybe_invoke_async_callback(htres); return; } if (htres->parent->flags & PYCBC_CONN_F_ASYNC) { maybe_invoke_async_callback(htres); return; } if (!--htres->parent->nremaining) { lcb_breakout(instance); } (void)instance; (void)req; }
/** Returns a list of all files referenced by an interpretation. It does this by looking at the file headers referenced by * the interpretation, following their parent pointers up to an SgAsmGenericFile node, and returning a vector of those nodes * with duplicate files removed. */ SgAsmGenericFilePtrList SgAsmInterpretation::get_files() const { const SgAsmGenericHeaderPtrList &headers = get_headers()->get_headers(); std::set<SgAsmGenericFile*> files; for (size_t i=0; i<headers.size(); i++) { SgAsmGenericHeader *header = headers[i]; SgAsmGenericFile *file = SageInterface::getEnclosingNode<SgAsmGenericFile>(header); ROSE_ASSERT(file!=NULL); files.insert(file); } return SgAsmGenericFilePtrList(files.begin(), files.end()); }
static void http_data_callback(lcb_http_request_t req, lcb_t instance, const void *cookie, lcb_error_t err, const lcb_http_resp_t *resp) { pycbc_HttpResult *htres = (pycbc_HttpResult*)cookie; htres->htcode = resp->v.v0.status; htres->rc = err; PYCBC_CONN_THR_END(htres->parent); get_headers(htres, resp); if (err != LCB_SUCCESS || resp->v.v0.status < 200 || resp->v.v0.status > 299) { PyObject *old_data = htres->http_data; lcbex_vrow_free(htres->rctx); htres->rctx = NULL; htres->http_data = PyList_New(0); if (old_data) { if (old_data != Py_None) { PyList_Append(htres->http_data, old_data); } Py_DECREF(old_data); } } if (htres->rctx) { lcbex_vrow_feed(htres->rctx, resp->v.v0.bytes, resp->v.v0.nbytes); } else if (resp->v.v0.bytes) { get_data(htres, resp->v.v0.bytes, resp->v.v0.nbytes); } if (!htres->parent->nremaining) { lcb_breakout(instance); } PYCBC_CONN_THR_BEGIN(htres->parent); (void)req; (void)instance; }
char *unarchive(FILE *src_stream, FILE *out_stream, file_header_t *(*get_headers)(FILE *), const int extract_function, const char *prefix, char **extract_names) { file_header_t *file_entry; int extract_flag; int i; char *buffer = NULL; archive_offset = 0; while ((file_entry = get_headers(src_stream)) != NULL) { extract_flag = TRUE; if (extract_names != NULL) { int found_flag = FALSE; for(i = 0; extract_names[i] != 0; i++) { if (strcmp(extract_names[i], file_entry->name) == 0) { found_flag = TRUE; break; } } if (extract_function & extract_exclude_list) { if (found_flag == TRUE) { extract_flag = FALSE; } } else { /* If its not found in the include list dont extract it */ if (found_flag == FALSE) { extract_flag = FALSE; } } } if (extract_flag == TRUE) { buffer = extract_archive(src_stream, out_stream, file_entry, extract_function, prefix); } else { /* seek past the data entry */ seek_sub_file(src_stream, file_entry->size); } free(file_entry->name); /* may be null, but doesn't matter */ free(file_entry->link_name); free(file_entry); } return(buffer); }
/** * This callback does things a bit differently. * Instead of using a MultiResult, we use a single HttpResult object. * We won't ever have "multiple" http objects. */ static void http_complete_callback(lcb_http_request_t req, lcb_t instance, const void *cookie, lcb_error_t err, const lcb_http_resp_t *resp) { pycbc_HttpResult *htres = (pycbc_HttpResult*)cookie; htres->htreq = NULL; if (!htres->parent) { return; } htres->rc = err; htres->htcode = resp->v.v0.status; if (htres->htflags & PYCBC_HTRES_F_CHUNKED) { /** No data here */ if (!pycbc_assert(resp->v.v0.nbytes == 0)) { fprintf(stderr, "Unexpected payload in HTTP response callback\n"); } if (!htres->parent->nremaining) { lcb_breakout(instance); } return; } PYCBC_CONN_THR_END(htres->parent); if (!--htres->parent->nremaining) { lcb_breakout(instance); } get_data(htres, resp->v.v0.bytes, resp->v.v0.nbytes); get_headers(htres, resp); PYCBC_CONN_THR_BEGIN(htres->parent); (void)instance; (void)req; }
std::vector<cv::Rect> DetectWithCT::detect0(size_t cnt, cv::Mat &origin, cv::Mat &prev, cv::Mat &curr, cv::vector<int> &dirs) { RECTS motion_rects = get_motion_rects_using_diff(prev, curr); RECTS all_headers; for (RECTS::const_iterator it = motion_rects.begin(); it != motion_rects.end(); ++it) { RECTS headers = get_headers(origin(*it)); for (size_t i = 0; i < headers.size(); i++) { headers[i].x += it->x; headers[i].y += it->y; all_headers.push_back(headers[i]); } } for (size_t i = 0; i < all_headers.size(); i++) { cv::rectangle(origin, all_headers[i], cv::Scalar(255, 255, 255), 2); } RECTS rcs; return rcs; }
intgen_t get_headerinfo( int fd, void **hdrs, void **cnt, size_t hdrsz, size_t cntsz, bool_t dolock ) { int num; /* get a lock on the table for reading */ if ( dolock ) INVLOCK( fd, LOCK_SH ); num = get_counters( fd, cnt, cntsz ); /* If there are no sessions recorded yet, we're done too */ if ( num > 0 ) { if ( get_headers( fd, hdrs, hdrsz * (size_t)num, cntsz ) < 0 ) { free ( *cnt ); num = -1; } } if ( dolock ) INVLOCK( fd, LOCK_UN ); return num; }
static void http_data_callback(lcb_http_request_t req, lcb_t instance, const void *cookie, lcb_error_t err, const lcb_http_resp_t *resp) { pycbc_HttpResult *htres = (pycbc_HttpResult*)cookie; htres->htcode = resp->v.v0.status; htres->rc = err; PYCBC_CONN_THR_END(htres->parent); get_headers(htres, resp); if (err != LCB_SUCCESS || resp->v.v0.status < 200 || resp->v.v0.status > 299) { lcbex_vrow_free(htres->rctx); htres->rctx = NULL; } if (htres->rctx) { lcbex_vrow_feed(htres->rctx, resp->v.v0.bytes, resp->v.v0.nbytes); maybe_invoke_async_callback(htres); } else if (resp->v.v0.bytes) { add_data(htres, resp->v.v0.bytes, resp->v.v0.nbytes); } if (!htres->parent->nremaining) { lcb_breakout(instance); } PYCBC_CONN_THR_BEGIN(htres->parent); (void)req; (void)instance; }
int proxy_server() { int rx_bytes = 0, post_data_size = 0; int lsock = 0, csock = 0, client_data_size = 0; int result_size = 0, err_code = 0, id = 0; int addrlen = sizeof(struct sockaddr_in); struct sockaddr_in clientaddr; char *buffer = NULL, *post_data = NULL; char *host = NULL, *url = NULL; char *query = NULL, *fifo_file = NULL; char *get_data = NULL; char *client_data = NULL, *headers = NULL; char *server_ip = NULL; memset((void *) &clientaddr,0,addrlen); server_ip = config_get_server_ip(); /* Create TCP socket */ if((lsock = create_socket(server_ip,PROXY_PORT,SOCK_STREAM)) == SOCK_FAIL) { glog("Failed to create TCP socket for proxy server",LOG_ERROR_TYPE); if(server_ip) free(server_ip); return EXIT_FAILURE; } if(server_ip) free(server_ip); /* Infinite receive loop */ while(1) { /* Accept incoming connection */ if((csock = accept(lsock,(struct sockaddr *) &clientaddr,(socklen_t *) &addrlen)) < 0) { glog("Failed to accept TCP connection to proxy server",LOG_ERROR_TYPE); if(buffer) free(buffer); return EXIT_FAILURE; } if(!fork()) { /* Receive client request */ if((buffer = receive(lsock,SOCK_STREAM,&rx_bytes,csock,&clientaddr)) == NULL) { glog("Failed to read data from client request sent to proxy server",LOG_ERROR_TYPE); exit(EXIT_FAILURE); } if(is_using_proxy(buffer)) { /* Get the target's IP address */ host = get_host_name(buffer); /* Get the target URL path */ url = get_url(buffer); /* Get POST data, if any */ post_data = get_post_data(buffer,rx_bytes,&post_data_size); /* Get HTTP headers from request */ headers = get_headers(buffer); /* If the CONSOLE_HOST is requested, then display the Web console interface */ if(memcmp(host,CONSOLE_HOST,CONSOLE_HOST_SIZE) == 0) { show_web_ui(csock,url); close_socket(csock); } else { /* Make sure the requested host is in our clients list */ query = sqlite3_mprintf("SELECT id FROM %s WHERE strftime('%%s',callback_time) >= strftime('%%s','now') AND ip = %Q LIMIT 1",CLIENTS_TABLE,host); sql_exec(query,&result_size,&err_code); sqlite3_free(query); if(result_size > 0) { /* Don't allow requests for filtered file extensions */ if(!is_url_filtered(url)) { fifo_file = create_fifo(host); if(!fifo_file) { glog("Failed to create fifo file",LOG_ERROR_TYPE); } else { /* Insert query into queue table */ query = sqlite3_mprintf("INSERT INTO %s (fifo,host,url,headers,pdata,sent) VALUES (%Q,%Q,%Q,%Q,%Q,0)",QUEUE_TABLE,fifo_file,host,url,headers,post_data); sql_exec(query,&result_size,&err_code); sqlite3_free(query); if(err_code != SQLITE_OK) { sql_log_error(); } else { /* When the client data has returned, the callback server will write the ID of the callback to the FIFO */ id = read_from_fifo(fifo_file); /* Extract the data from the DB */ get_data = sqlite3_mprintf("SELECT rdata FROM %s WHERE id = '%d'",QUEUE_TABLE,id); client_data = sql_exec(get_data,&client_data_size,&err_code); sqlite3_free(get_data); if(err_code != SQLITE_OK) { sql_log_error(); } else { /* Write data to socket */ if(write(csock,client_data,client_data_size) != client_data_size) { glog("Proxy socket write failed",LOG_ERROR_TYPE); } } if(client_data) free(client_data); /* Make sure the fifo gets deleted */ destroy_fifo(fifo_file); } } } } } } /* Exit the child process */ close_socket(csock); if(fifo_file) free(fifo_file); if(buffer) free(buffer); if(host) free(host); if(url) free(url); if(post_data) free(post_data); if(headers) free(headers); exit(EXIT_SUCCESS); } } /* Close up shop */ close_socket(csock); close_socket(lsock); return EXIT_FAILURE; }
static CURL* curl_request(lua_State* L, curl_state* state, int optionsIndex, int progressFnIndex, int headersIndex) { CURL* curl; state->L = 0; state->RefIndex = 0; state->S.ptr = NULL; state->S.len = 0; state->errorBuffer[0] = '\0'; state->headers = NULL; curl_init(); curl = curl_easy_init(); if (!curl) return NULL; curl_easy_setopt(curl, CURLOPT_URL, luaL_checkstring(L, 1)); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, state->errorBuffer); curl_easy_setopt(curl, CURLOPT_USERAGENT, "Premake/" PREMAKE_VERSION); if (optionsIndex && lua_istable(L, optionsIndex)) { lua_pushnil(L); while (lua_next(L, optionsIndex) != 0) { const char* key = luaL_checkstring(L, -2); if (!strcmp(key, "headers") && lua_istable(L, -1)) { get_headers(L, lua_gettop(L), &state->headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, state->headers); } else if (!strcmp(key, "progress") && lua_isfunction(L, -1)) { state->L = L; lua_pushvalue(L, -1); state->RefIndex = luaL_ref(L, LUA_REGISTRYINDEX); } else if (!strcmp(key, "userpwd") && lua_isstring(L, -1)) { curl_easy_setopt(curl, CURLOPT_USERPWD, luaL_checkstring(L, -1)); } else if (!strcmp(key, "username") && lua_isstring(L, -1)) { curl_easy_setopt(curl, CURLOPT_USERNAME, luaL_checkstring(L, -1)); } else if (!strcmp(key, "password") && lua_isstring(L, -1)) { curl_easy_setopt(curl, CURLOPT_PASSWORD, luaL_checkstring(L, -1)); } else if (!strcmp(key, "timeout") && lua_isnumber(L, -1)) { curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)luaL_checknumber(L, -1)); } else if (!strcmp(key, "timeoutms") && lua_isnumber(L, -1)) { curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, (long)luaL_checknumber(L, -1)); } else if (!strcmp(key, "sslverifyhost") && lua_isnumber(L, -1)) { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, (long)luaL_checknumber(L, -1)); } else if (!strcmp(key, "sslverifypeer") && lua_isnumber(L, -1)) { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, (long)luaL_checknumber(L, -1)); } // pop the value, leave the key for lua_next lua_pop(L, 1); } } else { if (progressFnIndex && lua_type(L, progressFnIndex) == LUA_TFUNCTION) { state->L = L; lua_pushvalue(L, progressFnIndex); state->RefIndex = luaL_ref(L, LUA_REGISTRYINDEX); } if (headersIndex && lua_istable(L, headersIndex)) { get_headers(L, headersIndex, &state->headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, state->headers); } } curl_easy_setopt(curl, CURLOPT_WRITEDATA, state); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_cb); if (state->L != 0) { curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, state); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, curl_progress_cb); } // clear error buffer. state->errorBuffer[0] = 0; return curl; }
int local_scan(int fd, uschar **return_text) { PyObject *user_dict; PyObject *user_func; PyObject *result; PyObject *header_tuple; PyObject *original_recipients; PyObject *working_recipients; if (!expy_enabled) return LOCAL_SCAN_ACCEPT; if (!Py_IsInitialized()) /* local_scan() may have already been run */ { Py_Initialize(); ExPy_Header_Line.ob_type = &PyType_Type; } if (!expy_exim_dict) { PyObject *module = Py_InitModule(expy_exim_module, expy_exim_methods); /* Borrowed reference */ Py_INCREF(module); /* convert to New reference */ expy_exim_dict = PyModule_GetDict(module); /* Borrowed reference */ Py_INCREF(expy_exim_dict); /* convert to New reference */ } if (!expy_user_module) { if (expy_path_add) { PyObject *sys_module; PyObject *sys_dict; PyObject *sys_path; PyObject *add_value; sys_module = PyImport_ImportModule("sys"); /* New Reference */ if (!sys_module) { PyErr_Clear(); *return_text = "Internal error, can't import Python sys module"; log_write(0, LOG_REJECT, "Couldn't import Python 'sys' module"); /* FIXME: write out an exception traceback if possible to Exim log */ return PYTHON_FAILURE_RETURN; } sys_dict = PyModule_GetDict(sys_module); /* Borrowed Reference, never fails */ sys_path = PyMapping_GetItemString(sys_dict, "path"); /* New reference */ if (!sys_path || (!PyList_Check(sys_path))) { PyErr_Clear(); /* in case sys_path was NULL, harmless otherwise */ *return_text = "Internal error, sys.path doesn't exist or isn't a list"; log_write(0, LOG_REJECT, "expy: Python sys.path doesn't exist or isn't a list"); /* FIXME: write out an exception traceback if possible to Exim log */ return PYTHON_FAILURE_RETURN; } add_value = PyString_FromString(expy_path_add); /* New reference */ if (!add_value) { PyErr_Clear(); log_write(0, LOG_PANIC, "expy: Failed to create Python string from [%s]", expy_path_add); return PYTHON_FAILURE_RETURN; } if (PyList_Append(sys_path, add_value)) { PyErr_Clear(); log_write(0, LOG_PANIC, "expy: Failed to append [%s] to Python sys.path", expy_path_add); } Py_DECREF(add_value); Py_DECREF(sys_path); Py_DECREF(sys_module); } expy_user_module = PyImport_ImportModule(expy_scan_module); /* New Reference */ if (!expy_user_module) { PyErr_Clear(); *return_text = "Internal error, can't import Python local_scan module"; log_write(0, LOG_REJECT, "Couldn't import Python '%s' module", expy_scan_module); return PYTHON_FAILURE_RETURN; } } user_dict = PyModule_GetDict(expy_user_module); /* Borrowed Reference, never fails */ user_func = PyMapping_GetItemString(user_dict, expy_scan_function); /* New reference */ if (!user_func) { PyErr_Clear(); *return_text = "Internal error, module doesn't have local_scan function"; log_write(0, LOG_REJECT, "Python %s module doesn't have a %s function", expy_scan_module, expy_scan_function); return PYTHON_FAILURE_RETURN; } /* so far so good, prepare to run function */ /* Copy exim variables */ expy_dict_int("debug_selector", debug_selector); expy_dict_int("host_checking", host_checking); expy_dict_string("interface_address", interface_address); expy_dict_int("interface_port", interface_port); expy_dict_string("message_id", message_id); expy_dict_string("received_protocol", received_protocol); expy_dict_string("sender_address", sender_address); expy_dict_string("sender_host_address", sender_host_address); expy_dict_string("sender_host_authenticated", sender_host_authenticated); expy_dict_string("sender_host_name", sender_host_name); expy_dict_int("sender_host_port", sender_host_port); expy_dict_int("fd", fd); /* copy some constants */ expy_dict_int("LOG_MAIN", LOG_MAIN); expy_dict_int("LOG_PANIC", LOG_PANIC); expy_dict_int("LOG_REJECT", LOG_REJECT); expy_dict_int("LOCAL_SCAN_ACCEPT", LOCAL_SCAN_ACCEPT); expy_dict_int("LOCAL_SCAN_ACCEPT_FREEZE", LOCAL_SCAN_ACCEPT_FREEZE); expy_dict_int("LOCAL_SCAN_ACCEPT_QUEUE", LOCAL_SCAN_ACCEPT_QUEUE); expy_dict_int("LOCAL_SCAN_REJECT", LOCAL_SCAN_REJECT); expy_dict_int("LOCAL_SCAN_REJECT_NOLOGHDR", LOCAL_SCAN_REJECT_NOLOGHDR); expy_dict_int("LOCAL_SCAN_TEMPREJECT", LOCAL_SCAN_TEMPREJECT); expy_dict_int("LOCAL_SCAN_TEMPREJECT_NOLOGHDR", LOCAL_SCAN_TEMPREJECT_NOLOGHDR); expy_dict_int("MESSAGE_ID_LENGTH", MESSAGE_ID_LENGTH); expy_dict_int("SPOOL_DATA_START_OFFSET", SPOOL_DATA_START_OFFSET); expy_dict_int("D_v", D_v); expy_dict_int("D_local_scan", D_local_scan); /* set the headers */ header_tuple = get_headers(); PyDict_SetItemString(expy_exim_dict, "headers", header_tuple); /* * make list of recipients, give module a copy to work with in * List format, but keep original tuple to compare against later */ original_recipients = get_recipients(); /* New reference */ working_recipients = PySequence_List(original_recipients); /* New reference */ PyDict_SetItemString(expy_exim_dict, "recipients", working_recipients); Py_DECREF(working_recipients); /* Try calling our function */ result = PyObject_CallFunction(user_func, NULL); /* New reference */ Py_DECREF(user_func); /* Don't need ref to function anymore */ /* Check for Python exception */ if (!result) { PyErr_Clear(); *return_text = "Internal error, local_scan function failed"; Py_DECREF(original_recipients); clear_headers(header_tuple); Py_DECREF(header_tuple); return PYTHON_FAILURE_RETURN; // FIXME: should write exception to exim log somehow } /* User code may have replaced recipient list, so re-get ref */ working_recipients = PyDict_GetItemString(expy_exim_dict, "recipients"); /* Borrowed reference */ Py_XINCREF(working_recipients); /* convert to New reference */ /* * reconcile original recipient list with what's present after * Python code is done */ if ((!working_recipients) || (!PySequence_Check(working_recipients)) || (PySequence_Size(working_recipients) == 0)) /* Python code either deleted exim.recipients alltogether, or replaced it with a non-list, or emptied out the list */ recipients_count = 0; else { int i; /* remove original recipients not on the working list, reverse order important! */ for (i = recipients_count - 1; i >= 0; i--) { PyObject *addr = PyTuple_GET_ITEM(original_recipients, i); /* borrowed ref */ if (!PySequence_Contains(working_recipients, addr)) expy_remove_recipient(i); } /* add new recipients not in the original list */ for (i = PySequence_Size(working_recipients) - 1; i >= 0; i--) { PyObject *addr = PySequence_GetItem(working_recipients, i); if (!PySequence_Contains(original_recipients, addr)) receive_add_recipient(PyString_AsString(addr), -1); Py_DECREF(addr); } } Py_XDECREF(working_recipients); /* No longer needed */ Py_DECREF(original_recipients); /* No longer needed */ clear_headers(header_tuple); Py_DECREF(header_tuple); /* No longer needed */ /* Deal with the return value, first see if python returned a non-empty sequence */ if (PySequence_Check(result) && (PySequence_Size(result) > 0)) { /* save first item */ PyObject *rc = PySequence_GetItem(result, 0); /* if more than one item, convert 2nd item to string and use as return text */ if (PySequence_Size(result) > 1) { PyObject *str; PyObject *obj = PySequence_GetItem(result, 1); /* New reference */ str = PyObject_Str(obj); /* New reference */ *return_text = string_copy(PyString_AsString(str)); Py_DECREF(obj); Py_DECREF(str); } /* drop the sequence, and focus on the first item we saved */ Py_DECREF(result); result = rc; } /* If we have an integer, return that to Exim */ if (PyInt_Check(result)) { int rc = PyInt_AsLong(result); Py_DECREF(result); return rc; } /* didn't return anything usable */ Py_DECREF(result); *return_text = "Internal error, bad return code"; log_write(0, LOG_REJECT, "Python %s.%s function didn't return integer", expy_scan_module, expy_scan_function); return PYTHON_FAILURE_RETURN; }