static void translate(char *filename) { int count = 0; char *text = get_file_text(filename); char *start = text; if (text == NULL) { fprintf(stderr,"file %s not found\n",filename); return; } printf("translating %s:",filename); String result(1000,1000); while (*text) { if (isalpha(*text)) { String name; int len = get_name(text,name); if (len <= 0) { send_error(filename, start,text,"invalid identifier found",false); exit(-1); } text += len; suif_hash_map<String,String>::iterator iter = renames.find(name); if (iter != renames.end()) { count ++; result += (*iter).second; } else result += name; } else { result.push(*text); text ++; } } write_text(filename,(const char *)result); printf("%d substitutions made\n",count); }// end translate
void reply_with_perror_errno (int err, const char *fs, ...) { CLEANUP_FREE char *buf1 = NULL; CLEANUP_FREE char *buf2 = NULL; va_list args; int r; va_start (args, fs); r = vasprintf (&buf1, fs, args); va_end (args); if (r == -1) { error: perror ("vasprintf"); exit (EXIT_FAILURE); } r = asprintf (&buf2, "%s: %s", buf1, strerror (err)); if (r == -1) goto error; send_error (err, buf2); }
static bool cmd_resps(int srv, struct message *response) { switch(current_request) { case(CMD_QUIT): case(CMD_END): case(CMD_PUSH): case(CMD_CLEAN): case(CMD_RESPS): case(CMD_RESPI): case(CMD_SIZE): case(CMD_NBCLI): case(CMD_NBSRV): case(CMD_NBRCV): case(CMD_NBSND): case(CMD_NBERR): case(CMD_MAXNSEC): case(CMD_MINNSEC): case(CMD_SUMNSEC): warnx("unexpected string from server"); send_error(srv, E_INVAL); break; case(CMD_POP): case(CMD_POPF): case(CMD_GET): case(CMD_GETF): printf("%s\n", response->p_string); break; case(CMD_GETALL): printf("%d - %s\n", getall_counter++, response->p_string); break; default: break; } return true; }
void* client_thread(void * client_queue) { int confd; status res; char* message = NULL; queue *cq = (queue *)client_queue; for(;;) { confd = dequeue(cq); printf("Connection %d\n acquired by thread %lu\n", confd, pthread_self()); /* Serve client until they close connection, or * there is an error when attempting to read/write to/from them */ do { /* Obtain the request message as a string ending in '\r\n\r\n */ if ((res = obtain_request(&message, confd)) != OK) { printf("Failed to obtain HTTP request from connection %d\n",confd); if (res != CONNECTION_ERROR) { res = send_error(res, confd); } } else { /* If request message recieved successfully */ res = respond_to(message, confd); } } while (res != CONNECTION_ERROR); printf("Closing connection %d for thread %lu\n",confd, pthread_self()); close(confd); } /* Should never get here, but if it does * might as well attempt to avoid any memory leaks */ free(message); return NULL; }
void kill_clients(int pipe, const char* msg) { struct client* p; /* Used to traverse clients linked list */ int socket_buff[1]; /* Send socket fd to main thread to remove from master fd list */ // LOCK : Make sure clients is not altered while removing all client connections pthread_mutex_lock(&clients_lock); if (clients->count > 0) { p = clients->head; while (p != NULL) { // Send the socket fd to the main thread to remove // it from the master fd list socket_buff[0] = p->socket; write(pipe, socket_buff, 1); // Make sure that the socket is removed from // the master list before preceding any farther // (Removes a race condition which would cause // select() to break) pthread_mutex_lock(&slock); while (done == 0) pthread_cond_wait(&sready, &slock); done = 0; pthread_mutex_unlock(&slock); send_error(p->socket, msg); close(p->socket); remove_client_ref(p->socket); p = clients->head; } } // UNLOCK pthread_mutex_unlock(&clients_lock); }
static void handle_cancel(Octstr *packet, Octstr *out, int sequence) { long mode = eat_int_parm(packet, 59, 1); Octstr *timestamp = eat_string_parm(packet, 60, 12); Octstr *destination = eat_string_parm(packet, 21, 20); if (logging == LOG_packets) { printf("RCV: Cancel"); if (mode != INT_MIN) printf(", mode %ld", mode); if (destination) printf(", dest '%s'", octstr_get_cstr(destination)); if (timestamp) printf(", time '%s'", octstr_get_cstr(timestamp)); printf("\n"); } if (mode < 0 || mode > 2) send_error(out, 56, sequence, "602", "bad mode"); else { if (logging == LOG_packets) printf("SND: OK\n"); send_packet(out, 56, sequence, 0); } }
void handle_init(MSICall *call, const MSIMessage *msg) { assert(call); LOGGER_DEBUG(call->session->messenger->log, "Session: %p Handling 'init' friend: %d", call->session, call->friend_number); if (!msg->capabilities.exists) { LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid capabilities on 'init'"); call->error = msi_EInvalidMessage; goto FAILURE; } switch (call->state) { case msi_CallInactive: { /* Call requested */ call->peer_capabilities = msg->capabilities.value; call->state = msi_CallRequested; if (invoke_callback(call, msi_OnInvite) == -1) { goto FAILURE; } } break; case msi_CallActive: { /* If peer sent init while the call is already * active it's probable that he is trying to * re-call us while the call is not terminated * on our side. We can assume that in this case * we can automatically answer the re-call. */ LOGGER_INFO(call->session->messenger->log, "Friend is recalling us"); MSIMessage out_msg; msg_init(&out_msg, requ_push); out_msg.capabilities.exists = true; out_msg.capabilities.value = call->self_capabilities; send_message(call->session->messenger, call->friend_number, &out_msg); /* If peer changed capabilities during re-call they will * be handled accordingly during the next step */ } break; case msi_CallRequested: // fall-through case msi_CallRequesting: { LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid state on 'init'"); call->error = msi_EInvalidState; goto FAILURE; } } return; FAILURE: send_error(call->session->messenger, call->friend_number, call->error); kill_call(call); }
/* <% ident(arg, "arg", 'arg'); %> Syntax checking is very relaxed and all arguments are considered a string. Example, the following are the same: <% ident(foo); %> <% ident('foo'); %> */ int parse_asp(const char *path) { char *buffer; char *cp; char *a, *b, *c; char x; int argc; char *argv[32]; char *ident; const aspapi_t *api; if (f_read_alloc_string(path, &buffer, 128 * 1024) < 0) { free(buffer); if (!header_sent) send_error(500, NULL, "Read error"); return 0; } if (!header_sent) send_header(200, NULL, mime_html, 0); // <% id(arg, arg); %> cp = buffer; while (*cp) { if ((b = strstr(cp, "%>")) == NULL) { web_puts(cp); break; } *b = 0; //xx <% <% %> //xx %> a = cp; while ((c = strstr(a, "<%")) != NULL) { a = c + 2; } if (a == cp) { *b = '%'; b += 2; web_write(cp, b - cp); cp = b; continue; } web_write(cp, (a - cp) - 2); cp = b + 2; while (*a == ' ') ++a; ident = a; while (((*a >= 'a') && (*a <= 'z')) || ((*a >= 'A') && (*a <= 'Z')) || ((*a >= '0') && (*a <= '9')) || (*a == '_')) { ++a; } if (ident == a) { #ifdef DEBUG syslog(LOG_WARNING, "Identifier not found in %s @%u", path, a - buffer); #endif continue; } b = a; while (*a == ' ') ++a; if (*a++ != '(') { #ifdef DEBUG syslog(LOG_WARNING, "Expecting ( in %s @%u", path, a - buffer); #endif continue; } *b = 0; // <% foo(123, "arg"); %> // a -----^ ^--- null // printf("\n[[['%s'\n", ident); argc = 0; while (*a) { while (*a == ' ') ++a; if (*a == ')') { FINAL: ++a; while ((*a == ' ') || (*a == ';')) ++a; if (*a != 0) break; for (api = aspapi; api->name; ++api) { if (strcmp(api->name, ident) == 0) { api->exec(argc, argv); break; } } a = NULL; /* int z; for (z = 0; z < argc; ++z) { printf(" %d '%s'\n", z, argv[z]); } */ break; } if (argc >= 32) { #ifdef DEBUG syslog(LOG_WARNING, "Error while parsing arguments in %s @%u", path, a - buffer); #endif break; } if ((*a == '"') || (*a == '\'')) { x = *a; argv[argc++] = a + 1; while ((*++a != x) && (*a != 0)) { if (*a == '\\') { if (*++a == 0) break; *(a - 1) = *a; } } if (*a == 0) break; *a++ = 0; } else { argv[argc++] = a; while ((*a != ',') && (*a != ')') && (*a != ' ') && (*a != 0)) ++a; } while (*a == ' ') ++a; if (*a == ')') { *a = 0; goto FINAL; } if (*a != ',') break; *a++ = 0; } #ifdef DEBUG if (a != NULL) syslog(LOG_WARNING, "Error while parsing arguments in %s @%u", path, a - buffer); #endif // printf("argc=%d]]]\n", argc); } free(buffer); return 1; }
int jrpc_client_call(struct jrpc_client *client, const char *method, struct json *params, struct json **response) { int fd, max_read_size; size_t bytes_read = 0; char *new_buffer, *end_ptr = NULL; struct jrpc_connection *conn; struct json *root, *request; request = json_create_object(); json_add_string_to_object(request, "method", method); json_add_item_to_object(request, "params", params); json_add_number_to_object(request, "id", client->id); send_request(&client->conn, json_to_string(request)); json_delete(request); // read conn = &client->conn; fd = conn->sock.fd; for (;;) { if (conn->pos == (conn->buffer_size - 1)) { conn->buffer_size *= 2; new_buffer = realloc(conn->buffer, conn->buffer_size); if (new_buffer == NULL) { perror("Memory error"); return -ENOMEM; } conn->buffer = new_buffer; memset(conn->buffer + conn->pos, 0, conn->buffer_size - conn->pos); } // can not fill the entire buffer, string must be NULL terminated max_read_size = conn->buffer_size - conn->pos - 1; if ((bytes_read = read(fd, conn->buffer + conn->pos, max_read_size)) == -1) { elog("read %d\n", strerror(errno)); return -EIO; } if (!bytes_read) { // client closed the sending half of the connection if (client->conn.debug_level) dlog("Client closed connection.\n"); return -EIO; } conn->pos += bytes_read; if ((root = json_parse_stream(conn->buffer, &end_ptr)) != NULL) { if (client->conn.debug_level > 1) { dlog("Valid JSON Received:\n%s\n", json_to_string(root)); } if (root->type == JSON_T_OBJECT) { struct json *id = json_get_object_item(root, "id"); if (id->type == JSON_T_STRING) { if (client->id != atoi(id->string)) goto out; } else if (id->type == JSON_T_NUMBER) { if (client->id != id->valueint) goto out; } client->id++; //shift processed request, discarding it memmove(conn->buffer, end_ptr, strlen(end_ptr) + 2); conn->pos = strlen(end_ptr); memset(conn->buffer + conn->pos, 0, conn->buffer_size - conn->pos - 1); *response = json_detach_item_from_object(root, "result"); if (*response == NULL) goto out; json_delete(root); return 0; } out: elog("INVALID JSON Received:\n---\n%s\n---\n", conn->buffer); json_delete(root); return -EINVAL; } else if (end_ptr != (conn->buffer + conn->pos)) { // did we parse the all buffer? If so, just wait for more. // else there was an error before the buffer's end if (client->conn.debug_level) { elog("INVALID JSON Received:\n---\n%s\n---\n", conn->buffer); } send_error(conn, JRPC_PARSE_ERROR, strdup("Parse error. Invalid JSON" " was received by the client."), NULL); return -EINVAL; } } }
int main(int argc, char *argv[]) { int sock; struct sockaddr_in server_address; struct sockaddr_in client_address; int client_address_size; unsigned short server_port; int loss_percentage; if (argc < 3 || argc > 4){ fprintf(stderr, "Usage: %s <Server Port> <Loss Percentage> [-d]\n", argv[0]); exit(1); } server_port = atoi(argv[1]); loss_percentage = atoi(argv[2]); if (argc == 4 && strcmp(argv[3], "-d") == 0) { printf("Debug mode on.\n"); debug = 1; } // Set up ARQ with loss_percentage and max packet size if (arq_init(loss_percentage, 0) < 0) { fprintf(stderr, "Unable to set up ARQ\n"); fprintf(stderr, "Invalid loss percentage - Must be between 0 and 100.\n"); exit(2); } // Create socket for incoming connections if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { fprintf(stderr, "Could not create socket."); exit(2); } memset(&server_address, 0, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htons(server_port); // Bind to the server address if (bind(sock, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) { fprintf(stderr, "Could not bind to server address."); exit(2); } printf("Server started...\n"); while(1) { client_address_size = sizeof(client_address); char *buffer = calloc(1, sizeof(char) * arq_get_max_packet_size()); if (arq_recvfrom(sock, buffer, arq_get_max_packet_size(), 0, (struct sockaddr *) &client_address, &client_address_size) < 0) { continue; } char *client = inet_ntoa(client_address.sin_addr); int split_size = 0; char **split_buffer = split(buffer, " ", &split_size); free(buffer); if (split_size > 0) { // Handle REQUEST if (strcmp(split_buffer[0], "REQUEST") == 0) { if (split_size >= 2) { // Got a request with a file name char *file = split_buffer[1]; printf("%s - Received request for %s\n", client, file); FILE *fp = fopen(file, "r"); if (!fp) { // Oh no the file error printf("%s - Could not open file %s\n", client, file); if (send_error(sock, (struct sockaddr *) &client_address, client_address_size) < 0) { fprintf(stderr, "%s - Unable to contact client.\n", client); } } else { // File was opened successfully printf("%s - Starting transfer\n", client); // 5 b/c number of bytes for "SEND " const int command_size = 5; int chunk_size = arq_get_max_data_size() - command_size; int read_chunk_size = 0; do { void *chunk = calloc((size_t) chunk_size, sizeof(char)); read_chunk_size = fread(chunk, 1, chunk_size, fp); if (read_chunk_size > 0) { buffer = calloc(arq_get_max_packet_size(), sizeof(char)); sprintf(buffer, "SEND %s", (char *) chunk); printf("%s - Sending data\n", client); int size = arq_sendto(sock, buffer, command_size + read_chunk_size, 0, (struct sockaddr *) &client_address, client_address_size); if (size < 0) { fprintf(stderr, "%s - Unable to contact client.\n", client); break; } free(buffer); } free(chunk); } while (read_chunk_size > 0); if (feof(fp) != 0) { // End of file was reached printf("%s - Transfer complete\n", client); printf("%s - Terminating connection\n", client); buffer = calloc(arq_get_max_packet_size(), sizeof(char)); strcpy(buffer, "EOF"); if (arq_sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr *) &client_address, client_address_size) < 0) { fprintf(stderr, "%s - Unable to contact client.\n", client); } printf("%s - Connection terminated\n", client); } else if (ferror(fp) != 0) { // An error occurred printf("%s - Error occurred while reading file %s\n", client, file); printf("%s - Terminating connection\n", client); if (send_error(sock, (struct sockaddr *) &client_address, client_address_size) < 0) { fprintf(stderr, "%s - Unable to contact client.\n", client); } printf("%s - Connection terminated\n", client); } fclose(fp); } } else { printf("%s - Incorrect arguments for REQUEST.\n", client); send_error(sock, (struct sockaddr *) &client_address, client_address_size); } } else { printf("%s - Unknown command.\n", client); } } else { printf("%s - Unsure what to do.\n", client); } for (int i = 0; i < split_size; i++) { free(split_buffer[i]); } free(split_buffer); free(buffer); } }
void *worker(void *data) { int hSocket; char pBuffer[BUFFER_SIZE]; char method[BUFFER_SIZE]; char path[BUFFER_SIZE]; while(1) { pthread_mutex_lock(&lock); while(num == 0) pthread_cond_wait(&empty, &lock); hSocket = queue[rem]; rem = (rem + 1) % Q_SIZE; num--; pthread_mutex_unlock(&lock); pthread_cond_signal(&full); /* Process information */ read(hSocket, pBuffer, BUFFER_SIZE); if(sscanf(pBuffer, "%[^ ] %[^ ]", method, path) < 2) { send_error(hSocket, BAD_REQUEST, "Not the accepted protocol"); continue; } if(strcasecmp(method, "get") != 0) { send_error(hSocket, NOT_IMPLEMENTED, "Only implemented GET"); continue; } char *path_ptr = path; if(path[0] == '/') path_ptr = &(path[1]); int len = strlen(path_ptr); if(*path_ptr == '/' || strcmp(path_ptr, "..") == 0 || strncmp(path_ptr, "../", 3) == 0 || strstr(path_ptr, "/../") != NULL || strcmp(&(path_ptr[len-3]), "/..") == 0) { send_error(hSocket, BAD_REQUEST, "Tried to access a private file"); continue; } FILE *f = fopen(path_ptr, "r"); if(f) { fgets(pBuffer, BUFFER_SIZE, f); write(hSocket, pBuffer, strlen(pBuffer)); } else { send_error(hSocket, NOT_FOUND, "Unable to locate file"); continue; } fclose(f); if(close(hSocket) == SOCKET_ERROR) { printf("Could not close socket\n"); continue; } } return NULL; }
int handle_request(int connfd) { char *buf = (char *) malloc(MAXLINE); char *method, *uri, *version; char *fullpath; int nread; struct stat fs; int is_dir; int error_code = 0, ret = 0; rio_t rio; rio_initb(&rio, connfd); nread = rio_readlineb(&rio, buf, MAXLINE - 1); if (nread == 0) { error_code = 400; goto fail; } else if (buf[nread - 1] != '\n') { error_code = 414; goto fail; } else { buf[nread - 1] = 0; if (nread >= 2 && buf[nread - 2] == '\r') { buf[nread - 2] = 0; } } method = buf; for (uri = method; *uri != 0; ++uri) { if (*uri == ' ') { *uri = 0; ++uri; break; } } for (version = uri; *version != 0; ++version) { if (*version == ' ') { *version = 0; ++version; break; } } if (*method == 0 || *uri == 0 || *version == 0) { /* missing some fields in http request header */ error_code = 400; goto fail; } if (strcmp(method, "GET") != 0) { /* only allow GET method */ error_code = 405; goto fail; } goto next; fail: free(buf); if (error_code > 0) { send_error(connfd, error_code); return 0; } next: /* translate path and dispatch HTTP request according to path */ uri = translate_path(uri); fullpath = (char *) malloc(strlen(uri) + 2); fullpath[0] = '.'; strcpy(fullpath + 1, uri); if (stat(fullpath, &fs) != 0) { send_error(connfd, 404); } else { is_dir = S_ISDIR(fs.st_mode); if (is_dir) { if (fullpath[(int) strlen(fullpath) - 1] != '/') { send_response(connfd, 301, NULL); send_header(connfd, "Location", "%s/", fullpath); end_headers(connfd); } else { ret = list_directory(connfd, fullpath); } } else { ret = fetch_file(connfd, fullpath); } } free(fullpath); free(buf); return ret; }
int main(int argc, char **argv) { ETERM *tuplep; ETERM *fnp, *argp; byte buf[1024]; sqlite3 *db; char *zErrMsg = 0; int rc; log = fopen("/tmp/sqlite_port.log", "a+"); fprintf(log, "******start log (%s)******\n", argv[1]); fflush(log); rc = sqlite3_open(argv[1], &db); if (rc) { sqlite3_close(db); exit(1); } erl_init(NULL, 0); while (read_cmd(buf) > 0) { tuplep = erl_decode(buf); fnp = erl_element(1, tuplep); argp = erl_element(2, tuplep); if (strncmp((const char *)ERL_ATOM_PTR(fnp), "close", 5) == 0) { fprintf(log, "closing sqlite3_close\n"); fflush(log); sqlite3_close(db); break; } else if (strncmp((const char *)ERL_ATOM_PTR(fnp), "list_tables", 11) == 0) { fprintf(log, "calling list_tables\n"); result = 0; rc = sqlite3_exec(db, MASTER_QUERY, list_tables, 0, &zErrMsg); if (rc != SQLITE_OK) { send_error(zErrMsg); sqlite3_free(zErrMsg); } else if (result != 0) { send_result(); } else { // not an error and no results. still need to return something send_ok(); } fflush(log); } else if (strncmp((const char *)ERL_ATOM_PTR(fnp), "sql_exec", 8) == 0) { fprintf(log, "calling sqlite3_exec %s\n", erl_iolist_to_string(argp)); result = 0; rc = sqlite3_exec(db, erl_iolist_to_string(argp), callback, 0, &zErrMsg); if (rc != SQLITE_OK) { send_error(zErrMsg); sqlite3_free(zErrMsg); } else if (result != 0) { send_result(); } else { // not an error and no results. still need to return something send_ok(); } fflush(log); } erl_free_compound(tuplep); erl_free_term(fnp); erl_free_term(argp); } fprintf(log, "******end log******\n"); fclose(log); return 0; }
void server::run() { network::connection sock = 0; time_t last_ts = monotonic_clock(); for(;;) { if(need_reload) { load_config(); // TODO: handle port number config changes need_reload = 0; last_ts = 0; LOG_CS << "Reloaded configuration\n"; } try { bool force_flush = false; std::string admin_cmd; if(input_ && input_->read_line(admin_cmd)) { control_line ctl = admin_cmd; if(ctl == "shut_down") { LOG_CS << "Shut down requested by admin, shutting down...\n"; break; } else if(ctl == "readonly") { if(ctl.args_count()) { cfg_["read_only"] = read_only_ = utils::string_bool(ctl[1], true); } LOG_CS << "Read only mode: " << (read_only_ ? "enabled" : "disabled") << '\n'; } else if(ctl == "flush") { force_flush = true; LOG_CS << "Flushing config to disk...\n"; } else if(ctl == "reload") { if(ctl.args_count()) { if(ctl[1] == "blacklist") { LOG_CS << "Reloading blacklist...\n"; load_blacklist(); } else { ERR_CS << "Unrecognized admin reload argument: " << ctl[1] << '\n'; } } else { LOG_CS << "Reloading all configuration...\n"; need_reload = 1; // Avoid flush timer ellapsing continue; } } else if(ctl == "setpass") { if(ctl.args_count() != 2) { ERR_CS << "Incorrect number of arguments for 'setpass'\n"; } else { const std::string& addon_id = ctl[1]; const std::string& newpass = ctl[2]; config& campaign = get_campaign(addon_id); if(!campaign) { ERR_CS << "Add-on '" << addon_id << "' not found, cannot set passphrase\n"; } else if(newpass.empty()) { // Shouldn't happen! ERR_CS << "Add-on passphrases may not be empty!\n"; } else { campaign["passphrase"] = newpass; write_config(); LOG_CS << "New passphrase set for '" << addon_id << "'\n"; } } } else { ERR_CS << "Unrecognized admin command: " << ctl.full() << '\n'; } } const time_t cur_ts = monotonic_clock(); // Write config to disk every ten minutes. if(force_flush || labs(cur_ts - last_ts) >= 10*60) { write_config(); last_ts = cur_ts; } network::process_send_queue(); sock = network::accept_connection(); if(sock) { LOG_CS << "received connection from " << network::ip_address(sock) << "\n"; } config data; while((sock = network::receive_data(data, 0)) != network::null_connection) { config::all_children_iterator i = data.ordered_begin(); if(i != data.ordered_end()) { // We only handle the first child. const config::any_child& c = *i; request_handlers_table::const_iterator j = handlers_.find(c.key); if(j != handlers_.end()) { // Call the handler. j->second(this, request(c.key, c.cfg, sock)); } else { send_error("Unrecognized [" + c.key + "] request.", sock); } } } } catch(network::error& e) { if(!e.socket) { ERR_CS << "fatal network error: " << e.message << "\n"; throw; } else { LOG_CS << "client disconnect: " << e.message << " " << network::ip_address(e.socket) << "\n"; e.disconnect(); } } catch(const config::error& e) { network::connection err_sock = 0; network::connection const * err_connection = boost::get_error_info<network::connection_info>(e); if(err_connection != NULL) { err_sock = *err_connection; } if(err_sock == 0 && sock > 0) { err_sock = sock; } if(err_sock) { ERR_CS << "client disconnect due to exception: " << e.what() << " " << network::ip_address(err_sock) << "\n"; network::disconnect(err_sock); } else { throw; } } SDL_Delay(20); } }
int process(FILE *f) { char buf[4096]; char *method; char *path; char *protocol; struct stat statbuf; char pathbuf[4096]; int len; if (!fgets(buf, sizeof(buf), f)) return -1; printf("URL: %s", buf); method = strtok(buf, " "); path = strtok(NULL, " "); protocol = strtok(NULL, "\r"); if (!method || !path || !protocol) return -1; fseek(f, 0, SEEK_CUR); // Force change of stream direction if (strcasecmp(method, "GET") != 0) send_error(f, 501, "Not supported", NULL, "Method is not supported."); else if (stat(path, &statbuf) < 0) send_error(f, 404, "Not Found", NULL, "File not found."); else if (S_ISDIR(statbuf.st_mode)) { len = strlen(path); if (len == 0 || path[len - 1] != '/') { snprintf(pathbuf, sizeof(pathbuf), "Location: %s/", path); send_error(f, 302, "Found", pathbuf, "Directories must end with a slash."); } else { snprintf(pathbuf, sizeof(pathbuf), "%sindex.html", path); if (stat(pathbuf, &statbuf) >= 0) send_file(f, pathbuf, &statbuf); else { DIR *dir; struct dirent *de; send_headers(f, 200, "OK", NULL, "text/html", -1, statbuf.st_mtime); fprintf(f, "<HTML><HEAD><TITLE>Index of %s</TITLE></HEAD>\r\n<BODY>", path); fprintf(f, "<H4>Index of %s</H4>\r\n<PRE>\n", path); fprintf(f, "Name Last Modified Size\r\n"); fprintf(f, "<HR>\r\n"); if (len > 1) fprintf(f, "<A HREF=\"..\">..</A>\r\n"); dir = opendir(path); while ((de = readdir(dir)) != NULL) { char timebuf[32]; struct tm *tm; strcpy(pathbuf, path); strcat(pathbuf, de->d_name); stat(pathbuf, &statbuf); tm = gmtime(&statbuf.st_mtime); strftime(timebuf, sizeof(timebuf), "%d-%b-%Y %H:%M:%S", tm); fprintf(f, "<A HREF=\"%s%s\">", de->d_name, S_ISDIR(statbuf.st_mode) ? "/" : ""); fprintf(f, "%s%s", de->d_name, S_ISDIR(statbuf.st_mode) ? "/</A>" : "</A> "); if (strlen(de->d_name) < 32) fprintf(f, "%*s", 32 - strlen(de->d_name), ""); if (S_ISDIR(statbuf.st_mode)) fprintf(f, "%s\r\n", timebuf); else fprintf(f, "%s %10d\r\n", timebuf, statbuf.st_size); } closedir(dir); fprintf(f, "</PRE>\r\n<HR>\r\n<ADDRESS>%s</ADDRESS>\r\n</BODY></HTML>\r\n", SERVER); } } } else send_file(f, path, &statbuf); return 0; }
void *plmc_client_mgr(void *arguments) { thread_entry *tentry; thread_data *tdata; char command[PLMC_CMD_NAME_MAX_LENGTH]; char result[PLMC_MAX_TCP_DATA_LEN]; char ee_id[PLMC_EE_ID_MAX_LENGTH]; PLMC_cmd_idx cmd_enum; int sockfd, retval, bytes_received; struct timeval tv; int( *callback)(tcp_msg *); tentry = (thread_entry *) arguments; tdata = &(tentry->thread_d); command[0] ='\0'; /* Adding 10 seconds to the plmc_cmd_timeout_secs in the * plmcd.conf file */ tv.tv_sec = config.plmc_cmd_timeout_secs + 10; tv.tv_usec = 0; tcp_msg tcpmsg; #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_client_mgr started up\n"); fflush(plmc_lib_debug); #endif /* Lock to get the socket */ if (pthread_mutex_lock(&tdata->td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: plmc_client_mgr encountered an " "error getting a lock for a client"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_EXIT_THREAD, NULL, PLMC_NOOP_CMD); pthread_exit((void *)NULL); } sockfd = tentry->thread_d.socketfd; strncpy(ee_id, tdata->ee_id, PLMC_EE_ID_MAX_LENGTH); ee_id[PLMC_EE_ID_MAX_LENGTH - 1] = '\0'; /* * There is a new command, copy it locally and return the * lock */ strncpy(command, tdata->command, PLMC_CMD_NAME_MAX_LENGTH); command[PLMC_CMD_NAME_MAX_LENGTH - 1] = '\0'; cmd_enum = plmc_cmd_string_to_enum(tdata->command); /* Get the callback as well */ callback = tdata->callback; /* Unlock */ if (pthread_mutex_unlock(&tdata->td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: encountered an " "error unlocking a client mutex"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_UNDEFINED, ee_id, cmd_enum); } #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_client_mgr got a new command %s for " "ee_id %s\n", command, ee_id); fflush(plmc_lib_debug); #endif /* * Change the socket option so that it waits for tv.tv_sec seconds * for a respons */ if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv) < 0) { syslog(LOG_ERR, "plmc_lib: encountered an error during " "a call to setsockopt() from client_mgr"); syslog(LOG_ERR, "plmc_lib: errnor is %d", errno); syslog(LOG_ERR, "plmc_lib: Closing socket and exiting " "client_mgr"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_EXIT_THREAD, ee_id, cmd_enum); if (close_socket(sockfd) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an error " "during a call to close_socket"); } pthread_exit((void *)NULL); } #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_client_mgr: Sending command to client\n"); fflush(plmc_lib_debug); #endif /* Send the command to PLMc */ retval = send(sockfd, command, strlen(command), 0); if (retval <= 0) { syslog(LOG_ERR, "plmc_lib: Client Mgr encountered an error " "during a call to send(). Leaving cleanup for " "connection mgr"); syslog(LOG_ERR, "plmc_lib: errnor is %d", errno); /* Connection MGR will send error to plmc_lib */ pthread_exit((void *)NULL); } /* Get the response */ bytes_received = recv(sockfd, result, PLMC_MAX_TCP_DATA_LEN, 0); if (bytes_received <= 0 ){ /* * The client didn't come back in time. Can't * hang around waiting for this guy. Close this * socket. He'll just have to reconnect */ syslog(LOG_ERR, "plmc_lib: Client Mgr encountered an " "error during a call to recv(). Leaving " "cleanup for connection mgr"); /* Send a timeout error */ send_error(PLMC_LIBERR_TIMEOUT, PLMC_LIBACT_CLOSE_SOCKET, ee_id, cmd_enum); /* Lock to change the socket */ if (pthread_mutex_lock(&tdata->td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: client_mgr encountered an " "error getting a lock for a client"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_EXIT_THREAD, ee_id, cmd_enum); pthread_exit((void *)NULL); } if (close_socket(sockfd) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an error " "during a call to close_socket"); } /* * Set socketfd to zero to indicate to connection_mgr * that we are gone */ tentry->thread_d.socketfd = 0; tdata->td_id = 0; tdata->kill = 1; if (pthread_mutex_unlock(&tdata->td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: plmc_client_mgr encountered " "an error unlocking a client mutex"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_UNDEFINED, ee_id, cmd_enum); } pthread_exit((void *)NULL); } result[bytes_received] = '\0'; #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_client_mgr: Got command back %s\n", result); fflush(plmc_lib_debug); #endif if (parse_tcp(&tcpmsg, result) != 0) { syslog(LOG_ERR, "plmc_lib: TCP message " "invalid %s", result); send_error(PLMC_LIBERR_MSG_INVALID, PLMC_LIBACT_IGNORING, ee_id, cmd_enum); pthread_exit((void *)NULL); } /* Get lock */ if (pthread_mutex_lock(&tdata->td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: client_mgr encountered an error " "getting a lock for a client"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_UNDEFINED, ee_id, cmd_enum); if (close_socket(sockfd) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an error during " "a call to close_socket"); } pthread_exit((void *)NULL); } /* Tell the world we are done with this guy */ tdata->done = 1; tdata->td_id = 0; /* We are exiting */ /* Unlock */ if (pthread_mutex_unlock(&tdata->td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: plmc_client_mgr encountered an " "error unlocking a client mutex"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_UNDEFINED, ee_id, cmd_enum); } /* Send callback */ if ((callback(&tcpmsg)) != 0) { syslog(LOG_ERR, "plmc_lib: encountered an error during the " "result callback call to PLMSv"); send_error(PLMC_LIBERR_ERR_CB, PLMC_LIBACT_IGNORING, ee_id, cmd_enum); pthread_exit((void *)NULL); } #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_client_mgr: Done with command, " "exiting\n"); fflush(plmc_lib_debug); #endif pthread_exit((void *)NULL); }
int list_directory(int connfd, const char *dirname) { char *buf; DIR *d; struct dirent *dir; struct stat fs; const char *item_fmt; const char *filename; char *fullname; int len1, len2, nwritten = 0; int ret; d = opendir(dirname); if (d) { buf = (char *) malloc(MAXBUF); /* TODO: escape or quote dirname / filename */ nwritten += snprintf(buf + nwritten, MAXBUF - nwritten, "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n" "<html>\n" "<title>Directory listing for %s</title>\n" "<body>\n" "<h2>Directory listing for %s</h2>\n" "<hr>\n" "<ul>\n", dirname + 1, dirname + 1); while ((dir = readdir(d)) != NULL) { filename = dir->d_name; if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) { continue; } else { len1 = strlen(dirname); len2 = strlen(filename); fullname = (char *) malloc(len1 + len2 + 1); strcpy(fullname, dirname); strcpy(fullname + len1, filename); fullname[len1 + len2] = 0; if (strcasecmp(filename, "index.html") == 0 || strcasecmp(filename, "index.htm") == 0) { ret = fetch_file(connfd, fullname); free(fullname); free(buf); closedir(d); return ret; } else { stat(fullname, &fs); if (S_ISDIR(fs.st_mode)) { item_fmt = "<li><a href=\"%s/\">%s/</a>\n"; } else { item_fmt = "<li><a href=\"%s\">%s</a>\n"; } nwritten += snprintf(buf + nwritten, MAXBUF - nwritten, item_fmt, filename, filename); } free(fullname); } } closedir(d); nwritten += snprintf(buf + nwritten, MAXBUF - nwritten, "</ul>\n" "<hr>\n" "</body>\n" "</html>\n"); send_response(connfd, 200, NULL); send_header(connfd, "Content-Type", "text/html"); send_header(connfd, "Content-Length", "%d", nwritten); end_headers(connfd); rio_writen(connfd, buf, nwritten); free(buf); return 1; } send_error(connfd, 404); return 0; }
///------------------------------------------------------------------------------------------------- /// Scan a single file. Everything that applies to ms_scan also applies to this function. If /// you know the type of the file, set the type paramter to one of TYPE_AUDIO, TYPE_VIDEO, or /// TYPE_IMAGE. Set it to TYPE_UNKNOWN to have it determined automatically. /// /// @author Andy Grundman /// @date 03/15/2011 /// /// @param [in,out] s If non-null, the. /// @param full_path Full pathname of the full file. /// /// ### remarks . ///------------------------------------------------------------------------------------------------- void ms_scan_file(MediaScan *s, const char *full_path, enum media_type type) { MediaScanError *e = NULL; MediaScanResult *r = NULL; int ret; uint32_t hash; int mtime = 0; uint64_t size = 0; DBT key, data; char tmp_full_path[MAX_PATH_STR_LEN]; #ifdef WIN32 char *ext = strrchr(full_path, '.'); #endif if (s == NULL) { ms_errno = MSENO_NULLSCANOBJ; LOG_ERROR("MediaScan = NULL, aborting scan\n"); return; } if (s->on_result == NULL) { ms_errno = MSENO_NORESULTCALLBACK; LOG_ERROR("Result callback not set, aborting scan\n"); return; } #if (defined(__APPLE__) && defined(__MACH__)) if (isAlias(full_path)) { LOG_INFO("File %s is a mac alias\n", full_path); // Check if this file is a shortcut and if so resolve it if (!CheckMacAlias(full_path, tmp_full_path)) { LOG_ERROR("Failure to follow symlink or alias, skipping file\n"); return; } } else { strcpy(tmp_full_path, full_path); } #elif defined(__unix__) || defined(__unix) if (isAlias(full_path)) { LOG_INFO("File %s is a unix symlink\n", full_path); // Check if this file is a shortcut and if so resolve it FollowLink(full_path, tmp_full_path); } else { strcpy(tmp_full_path, full_path); } #elif defined(WIN32) if (strcasecmp(ext, ".lnk") == 0) { // Check if this file is a shortcut and if so resolve it parse_lnk(full_path, tmp_full_path, MAX_PATH_STR_LEN); if (PathIsDirectory(tmp_full_path)) return; } else { strcpy(tmp_full_path, full_path); } #endif // Check if the file has been recently scanned hash = HashFile(tmp_full_path, &mtime, &size); // Skip 0-byte files if (unlikely(size == 0)) { LOG_WARN("Skipping 0-byte file: %s\n", tmp_full_path); return; } // Setup DBT values memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); key.data = (char *)full_path; key.size = strlen(full_path) + 1; data.data = &hash; data.size = sizeof(uint32_t); if ((s->flags & MS_RESCAN) || (s->flags & MS_FULL_SCAN)) { // s->dbp will be null if this function is called directly, if not check if this file is // already scanned. if (s->dbp != NULL) { // DB_GET_BOTH will only return OK if both key and data match, this avoids the need to check // the returned data against hash int ret = s->dbp->get(s->dbp, NULL, &key, &data, DB_GET_BOTH); if (ret != DB_NOTFOUND) { // LOG_INFO("File %s already scanned, skipping\n", tmp_full_path); return; } } } LOG_INFO("Scanning file %s\n", tmp_full_path); if (type == TYPE_UNKNOWN || type == TYPE_LNK) { // auto-detect type type = _should_scan(s, tmp_full_path); if (!type) { if (s->on_error) { ms_errno = MSENO_SCANERROR; e = error_create(tmp_full_path, MS_ERROR_TYPE_UNKNOWN, "Unrecognized file extension"); send_error(s, e); return; } } } r = result_create(s); if (r == NULL) return; r->type = type; r->path = strdup(full_path); if (result_scan(r)) { // These were determined by HashFile r->mtime = mtime; r->size = size; r->hash = hash; // Store path -> hash data in cache if (s->dbp != NULL) { memset(&data, 0, sizeof(DBT)); data.data = &hash; data.size = sizeof(uint32_t); ret = s->dbp->put(s->dbp, NULL, &key, &data, 0); if (ret != 0) { s->dbp->err(s->dbp, ret, "Cache store failed: %s", db_strerror(ret)); } } send_result(s, r); } else { if (s->on_error && r->error) { // Copy the error, because the original will be cleaned up by result_destroy below MediaScanError *ecopy = error_copy(r->error); send_error(s, ecopy); } result_destroy(r); } } /* ms_scan_file() */
static void handle_submit(Octstr *packet, Octstr *out, int sequence) { Octstr *dest_addr = eat_string_parm(packet, 21, 20); Octstr *orig_addr = eat_string_parm(packet, 23, 20); long DCS = eat_int_parm(packet, 30, 3); Octstr *UDH = eat_string_parm(packet, 32, 280); Octstr *text = eat_string_parm(packet, 33, 480); Octstr *textb = eat_string_parm(packet, 34, 280); long valid_rel = eat_int_parm(packet, 50, 3); Octstr *valid_abs = eat_string_parm(packet, 51, 12); long proto_id = eat_int_parm(packet, 52, 3); long delivery_rel = eat_int_parm(packet, 53, 3); Octstr *delivery_abs = eat_string_parm(packet, 54, 12); long reply_path = eat_int_parm(packet, 55, 1); long SRR = eat_int_parm(packet, 56, 2); long cancel = eat_int_parm(packet, 58, 1); long tariff_class = eat_int_parm(packet, 64, 2); long service_desc = eat_int_parm(packet, 65, 1); long priority = eat_int_parm(packet, 67, 1); List *other_dests = list_create(); Octstr *tmp; while ((tmp = eat_string_parm(packet, 21, 20))) list_append(other_dests, tmp); if (logging == LOG_packets) { int i; printf("RCV: Submit to %s", octstr_get_cstr(dest_addr)); for (i = 0; i < list_len(other_dests); i++) { printf(", %s", octstr_get_cstr(list_get(other_dests, i))); } printf("\n"); if (orig_addr) printf(" From: %s\n", octstr_get_cstr(orig_addr)); if (DCS > INT_MIN) printf(" Data coding: %ld\n", DCS); if (UDH) printf(" User data header: %s\n", octstr_get_cstr(UDH)); if (text) printf(" Text: %s\n", octstr_get_cstr(text)); if (textb) printf(" Text (binary): %s\n", octstr_get_cstr(textb)); if (valid_rel > INT_MIN) printf(" Validity period: %ld (relative)\n", valid_rel); if (valid_abs) printf(" Validity period: %s (absolute)\n", octstr_get_cstr(valid_abs)); if (proto_id > INT_MIN) printf(" Protocol ID: %ld\n", proto_id); if (delivery_rel > INT_MIN) printf(" First delivery: %ld (relative)\n", delivery_rel); if (delivery_abs) printf(" First delivery: %s (absolute)\n", octstr_get_cstr(delivery_abs)); if (reply_path == 0) printf(" Reply path disabled\n"); else if (reply_path == 1) printf(" Reply path enabled\n"); else if (reply_path > INT_MAX) printf(" Reply path: %ld\n", reply_path); if (SRR > INT_MAX) printf(" Status report flags: %ld\n", SRR); if (cancel == 0) printf(" Cancel disabled\n"); else if (cancel == 1) printf(" Cancel enabled\n"); else if (cancel > INT_MAX) printf(" Cancel enabled: %ld\n", cancel); if (tariff_class > INT_MAX) printf(" Tariff class: %ld\n", tariff_class); if (service_desc > INT_MAX) printf(" Service description: %ld\n", service_desc); if (priority > INT_MAX) printf(" Priority: %ld\n", priority); } if (!dest_addr) { send_error(out, 53, sequence, "300", "no destination"); } else if (list_len(other_dests) > 0) { send_error(out, 53, sequence, "301", "too many destinations"); /* TODO: Report many other possible errors here */ } else { unsigned char buf[TIMESTAMP_MAXLEN]; make_timestamp(buf, time(NULL)); if (logging == LOG_packets) printf("SND: Submit OK\n"); send_packet(out, 53, sequence, 21, octstr_get_cstr(dest_addr), 60, buf, 0); } octstr_destroy(dest_addr); octstr_destroy(orig_addr); octstr_destroy(UDH); octstr_destroy(text); octstr_destroy(textb); octstr_destroy(valid_abs); octstr_destroy(delivery_abs); list_destroy(other_dests, octstr_destroy_item); }
// Called by ms_scan either in a thread or synchronously static void *do_scan(void *userdata) { MediaScan *s = ((thread_data_type *)userdata)->s; int i; struct dirq *dir_head = (struct dirq *)s->_dirq; struct dirq_entry *dir_entry = NULL; struct fileq *file_head = NULL; struct fileq_entry *file_entry = NULL; char tmp_full_path[MAX_PATH_STR_LEN]; // Initialize the cache database if (!init_bdb(s)) { MediaScanError *e = error_create("", MS_ERROR_CACHE, "Unable to initialize libmediascan cache"); send_error(s, e); goto out; } if (s->flags & MS_CLEARDB) { reset_bdb(s); } if (s->progress == NULL) { MediaScanError *e = error_create("", MS_ERROR_TYPE_INVALID_PARAMS, "Progress object not created"); send_error(s, e); goto out; } // Build a list of all directories and paths // We do this first so we can present an accurate scan eta later progress_start_phase(s->progress, "Discovering"); for (i = 0; i < s->npaths; i++) { LOG_INFO("Scanning %s\n", s->paths[i]); recurse_dir(s, s->paths[i], 0); } // Scan all files found progress_start_phase(s->progress, "Scanning"); while (!SIMPLEQ_EMPTY(dir_head)) { dir_entry = SIMPLEQ_FIRST(dir_head); file_head = dir_entry->files; while (!SIMPLEQ_EMPTY(file_head)) { // check if the scan has been aborted if (s->_want_abort) { LOG_DEBUG("Aborting scan\n"); goto aborted; } file_entry = SIMPLEQ_FIRST(file_head); // Construct full path strcpy(tmp_full_path, dir_entry->dir); #ifdef WIN32 strcat(tmp_full_path, "\\"); #else strcat(tmp_full_path, "/"); #endif strcat(tmp_full_path, file_entry->file); ms_scan_file(s, tmp_full_path, file_entry->type); // Send progress update if necessary if (s->on_progress) { s->progress->done++; if (progress_update(s->progress, tmp_full_path)) send_progress(s); } SIMPLEQ_REMOVE_HEAD(file_head, entries); free(file_entry->file); free(file_entry); } SIMPLEQ_REMOVE_HEAD(dir_head, entries); free(dir_entry->dir); free(dir_entry->files); free(dir_entry); } // Send final progress callback if (s->on_progress) { progress_update(s->progress, NULL); send_progress(s); } LOG_DEBUG("Finished scanning\n"); out: if (s->on_finish) send_finish(s); aborted: if (s->async) { LOG_MEM("destroy thread_data @ %p\n", userdata); free(userdata); } return NULL; }
void *http_process(void *args) { int32 fd; struct http_request *req; int8 *cp = NULL; int8 *line = NULL; int8 *method = NULL; int8 *url = NULL; int8 *protocol = NULL; struct timeval timo; int32 optval = 1; int32 rc, rc_r, rc_s; int32 r = 0; if (NULL == args) return NULL; req = (struct http_request *)args; fd = req->fd; req->buff = malloc(BUFFSIZ); req->buff_size = BUFFSIZ; if (NULL == req->buff) { HTTPD_ERR("get_request_line malloc %d fail\n", BUFFSIZ); free(args); return NULL; } memset(req->buff, 0, BUFFSIZ); rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)); if (rc < 0) HTTPD_ERR("setsockopt error rc=%d errno=%d %s\n", rc, errno, strerror(errno)); timo.tv_sec = HTTPD_TIMO; timo.tv_usec = 0; rc_r = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timo, sizeof(timo)); rc_s = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timo, sizeof(timo)); if (rc_r < 0 || rc_s < 0) HTTPD_ERR("setsockopt error fd=%d rc=%d rc_r=%d rc_s=%d errno=%d %s\n", fd, rc, rc_r, rc_s, errno, strerror(errno)); /* GET / HTTP/1.1 */ method = get_request_line(req); if (method == NULL) goto close_task; url = parse_reqline(fd, method); if (url == NULL) goto close_task; protocol = parse_reqline(fd, url); if (protocol == NULL) goto close_task; req->method = http_method(method); if (req->method == M_OPTIONS) { send_error(fd, 204, "No Content", NULL, "Method OPTIONS."); goto close_task; } if (req->method == M_UNKNOWN) { send_error(fd, 400, "Bad Request", NULL, "Method Not Support."); goto close_task; } decode_url(req, url); HTTPD_INFO("method[%s] protocol[%s] url[%s] path[%s] query[%s]!\n", method, protocol, url, req->path, req->query ? : ""); while ((line = get_request_line(req)) != NULL) { if (line[0] == '\0') break; if (strncasecmp(line, "Upgrade:", 8) == 0) { cp = &line[8]; cp += strspn(cp, " \t"); if (strncasecmp(cp, "websocket", 9) == 0) req->is_websocket = 1; } else if (strncasecmp(line, "Connection:", 11) == 0) { cp = &line[11]; cp += strspn(cp, " \t"); /* Firefox: [Connection: keep-alive, Upgrade] */ if (strcasestr(cp, "Upgrade") != NULL) req->is_connection_upgrade = 1; } else if (strncasecmp(line, "Sec-WebSocket-Key:", 18) == 0) { cp = &line[18]; cp += strspn(cp, " \t"); req->sec_websocket_key = cp; } else if (strncasecmp(line, "Origin:", 7) == 0) { cp = &line[7]; cp += strspn(cp, " \t"); req->origin = cp; } else if (strncasecmp(line, "Sec-WebSocket-Version:", 22) == 0) { cp = &line[22]; cp += strspn(cp, " \t"); req->sec_websocket_version = atoi(cp); } else if (strncasecmp(line, "Content-Length:", 15) == 0) { cp = &line[15]; cp += strspn(cp, " \t"); req->content_length = atol(cp); if ((BUFFSIZ < req->content_length + MAX_HEADER_LEN) && (req->buff_size != req->content_length + MAX_HEADER_LEN) + 1) { re_alloc_buff(req); memset(req->buff + BUFFSIZ, 0, req->buff_size - BUFFSIZ); } } else if (strncasecmp(line, "Content-Type:", 13) == 0) { cp = &line[13]; cp += strspn(cp, " \t"); req->content_type = cp; } else if (strncasecmp(line, "Host:", 5) == 0) { cp = &line[5]; cp += strspn(cp, " \t"); req->host = cp; } } HTTPD_INFO("Left %d bytes HTTP data with Content-Length: %ld req->sz[%d] req->pos[%d]\n", req->sz - req->pos, req->content_length, req->sz, req->pos); if (line == NULL || req->path[0] != '/') send_error(fd, 400, "Bad Request", NULL, "Bad Request!"); if ((0 != req->content_length) && (req->sz != req->hd_sz + req->content_length)) { while ((r = http_read(req->fd, req->buff + req->sz, req->buff_size - req->sz)) > 0) { req->sz += r; if (req->sz == req->hd_sz + req->content_length) break; } } if (req->is_websocket) ws_process(req); else { uint32 i = 0; int8 *file = NULL; int8 *path = req->path; int8 *pTmp = path; int8 prefix[PREFIX_LEN] = {0}; int8 new_link[MAX_URL + 8] = {0}; rmm_cfg_get_rest_prefix(prefix, PREFIX_LEN); /*snprintf(new_link, (MAX_URL + 8), "%s%s", prefix, "/rack");*/ snprintf_s_s(new_link, (MAX_URL + 8), "%s", prefix); /*TODO: move to correct place */ get_json_pointer(req); /* remove redundant '/' */ for (; *(path+i) != '\0'; i++) { if ((*(path+i) == '/') && (*(path+i+1) == '/')) continue; *pTmp++ = *(path+i); } *pTmp = '\0'; if ((path[1] == '\0') || (strncasecmp(path, new_link, strnlen_s(new_link, sizeof(new_link)-1)) == 0)) file = NULL; else file = path; if (file != NULL) send_file(req->fd, file); else rest_process(req); } close_task: close(fd); if (NULL != req->buff) { free(req->buff); req->buff = NULL; } HTTPD_INFO("\nrest_req_thread[%lld] exit, fd[%d], errno:%d %s\n", (uint64)(req->tid_rest_req), fd, errno, strerror(errno)); free(args); pthread_detach(pthread_self()); return NULL; }
int process_cmd(FILE *fp, char *command, int buffer_size, char *buffer) { if (!strcmp(command, "/rapl_domains_count") || !strncmp(command, "/rapl_domains_count/", strlen("/rapl_domains_count/"))) { int count; count = powercap_get_rapl_domain_count(command); printf("rapl domain count %d\n", count); snprintf(buffer, buffer_size, "%d", count); send_success_response_plain(fp, buffer); } else if (!strncmp(command, "/rapl_domain_name/", strlen("/rapl_domain_name/"))) { if (read_domain_name(command, buffer_size, buffer) == STATUS_SUCCESS) send_success_response_plain(fp, buffer); else send_error(fp, "Sysfs error", "500", "sysfs read error", "name read failed"); } else if (!strncmp(command, "/rapl_domain_energy/", strlen("/rapl_domain_energy/"))) { if (read_domain_energy(command, buffer_size, buffer) == STATUS_SUCCESS) send_success_response_plain(fp, buffer); else send_error(fp, "Sysfs error", "500", "sysfs read error", "energy read failed"); } else if (!strncmp(command, "/rapl_domain_max_energy/", strlen("/rapl_domain_max_energy/"))) { if (read_domain_max_energy(command, buffer_size, buffer) == STATUS_SUCCESS) send_success_response_plain(fp, buffer); else send_error(fp, "Sysfs error", "500", "sysfs read error", "energy read failed"); } else if (!strcmp(command, "/") || !strcmp(command, "/index.html")) { int content_len; char local_ip_buffer[128]; if (local_host_name[0] != '\0') content_len = snprintf(local_ip_buffer, sizeof(local_ip_buffer), "var root_path = 'http://%s:%d/';\n", local_host_name, local_port_id); else content_len = snprintf(local_ip_buffer, sizeof(local_ip_buffer), "var root_path = 'http://%s:%d/';\n", local_ip_addr, local_port_id); if (local_index_html) { FILE *src_fp; int size; int ch; src_fp = fopen(local_index_html_file, "r"); if (!src_fp) { send_error(fp, "Page not found", "404", "Not found", "Requested URI not found"); return TRUE; } fseek(src_fp, 0L, SEEK_END); size = ftell(src_fp); fseek(src_fp, 0L, SEEK_SET); send_success(fp, size); while(!feof(src_fp)) { ch = fgetc(src_fp); fputc(ch, fp); } fclose(src_fp); } else { content_len += strlen(index_html_contents_header); content_len += strlen(index_html_contents_contents); send_success(fp, content_len); fprintf(fp, "%s\n", index_html_contents_header); fprintf(fp, "%s\n", local_ip_buffer); fprintf(fp, "%s\n", index_html_contents_contents); } } else if (!strncmp(command, "/terminate", strlen("/terminate"))) { return FALSE; } else { send_error(fp, "Page not found", "404", "Not found", "Requested URI not found"); } return TRUE; }
static void connection_cb(struct uloop_fd *sock, unsigned int events) { struct json *root; int fd, max_read_size; struct jrpc_connection *conn; struct jrpc_server *server; ssize_t bytes_read = 0; char *new_buffer, *end_ptr = NULL; conn = container_of(sock, struct jrpc_connection, sock); fd = sock->fd; server = conn->server; if (conn->pos == (conn->buffer_size - 1)) { conn->buffer_size *= 2; new_buffer = realloc(conn->buffer, conn->buffer_size); if (new_buffer == NULL) { elog("Memory error %s\n", strerror(errno)); return close_connection(sock); } conn->buffer = new_buffer; memset(conn->buffer + conn->pos, 0, conn->buffer_size - conn->pos); } // can not fill the entire buffer, string must be NULL terminated max_read_size = conn->buffer_size - conn->pos - 1; do { bytes_read = read(fd, conn->buffer + conn->pos, max_read_size); if (bytes_read < 0) { if (errno == EINVAL) continue; if (errno == EAGAIN) break; // error return close_connection(sock); } if (bytes_read == 0) { // client closed the sending half of the connection if (server->debug_level) dlog("Client closed connection.\n"); return close_connection(sock); } break; } while (1); conn->pos += bytes_read; if ((root = json_parse_stream(conn->buffer, &end_ptr)) != NULL) { if (server->debug_level > 1) { dlog("Valid JSON Received:\n%s\n", json_to_string(root)); } if (root->type == JSON_T_OBJECT) { eval_request(server, conn, root); } //shift processed request, discarding it memmove(conn->buffer, end_ptr, strlen(end_ptr) + 2); conn->pos = strlen(end_ptr); memset(conn->buffer + conn->pos, 0, conn->buffer_size - conn->pos - 1); json_delete(root); } else { // did we parse the all buffer? If so, just wait for more. // else there was an error before the buffer's end if (end_ptr != (conn->buffer + conn->pos)) { if (server->debug_level) { dlog("INVALID JSON Received:\n---\n%s\n---\n", conn->buffer); } send_error(conn, JRPC_PARSE_ERROR, strdup("Parse error. Invalid JSON" " was received by the server."), NULL); return close_connection(sock); } } }
static int start_server(char *interface) { struct sockaddr_in client_addr; socklen_t client_len; int client_fd; char *client_ip_addr; struct hostent *client_host; FILE *fp; char *buffer; char *uri; char *method; int continue_proc = TRUE; if (init_tcp(interface) < 0) { fprintf(stderr, "init TCP failed\n"); return STATUS_ERROR; } if (!interface) strcpy(local_ip_addr, "localhost"); client_len = sizeof(client_addr); while (continue_proc) { client_fd = accept(server_fd, (struct sockaddr *) &client_addr, &client_len); if (client_fd < 0) { perror("errorn in accept"); continue; } client_host = gethostbyaddr( (const char *) &client_addr.sin_addr.s_addr, sizeof(client_addr.sin_addr.s_addr), AF_INET); if (client_host == NULL) { perror("error in gethostbyaddr"); /* No need to bail out */ } client_ip_addr = inet_ntoa(client_addr.sin_addr); if (client_ip_addr == NULL) { perror("Can't get client IP\n"); close(client_fd); continue; } set_socket_timeout(client_fd); fprintf(stdout, "Received Request from %s\n", client_ip_addr); fp = fdopen(client_fd, "r+"); if (fp == NULL) { perror("error in fdopen"); close(client_fd); continue; } buffer = malloc(MAX_BUFFER_SIZE); if (!buffer) { perror("error in malloc"); fclose(fp); close(client_fd); continue; } if (fgets(buffer, MAX_BUFFER_SIZE, fp) == NULL) goto continue_loop; uri = NULL; method = NULL; method = strtok(buffer, " "); if (!method) { flush_request_buffer(fp); send_error(fp, "none", "400", "Bad request", "unknown method"); goto continue_loop; } if (strncasecmp(method, "GET", 3)) { flush_request_buffer(fp); send_error(fp, method, "501", "Not Implemented", "Only GET is supported"); goto continue_loop; } uri = strtok(NULL, " "); if (!uri) { flush_request_buffer(fp); send_error(fp, method, "400", "Bad request", "Bad request"); goto continue_loop; } flush_request_buffer(fp); if (!process_cmd(fp, uri, MAX_BUFFER_SIZE, buffer)) continue_proc = FALSE; fprintf(stdout, "processing done\n"); continue_loop: free(buffer); fclose(fp); close(client_fd); } return STATUS_SUCCESS; }
void web_handler(int client_socket) { printf("web_handler"); int j, file_fd, buflen; long i, ret, len; char * fstr; static char buffer[BUFSIZE + 1]; ret = read(client_socket, buffer, BUFSIZE); if(ret <= 0) send_error(400); else if (ret < BUFSIZE) buffer[ret] = 0; else buffer[0] = 0; if(strncmp(buffer,"GET ", 4)) send_error(500); for(i=4; i<BUFSIZE; i++) { if(buffer[i] == ' ') { buffer[i] = 0; break; } } for(j=0;j<i-1;j++) if(buffer[j] == '.' && buffer[j+1] == '.') send_error(403); if(!strncmp(&buffer[0],"GET /\0", 6)) (void)strcpy(buffer,"GET /index.html"); buflen=strlen(buffer); fstr = (char *)0; for(i=0;mime_info_map[i].ext != 0;i++) { len = strlen(mime_info_map[i].ext); if( !strncmp(&buffer[buflen-len], mime_info_map[i].ext, len)) { fstr =mime_info_map[i].filetype; break; } } if(fstr == 0) send_error(500); if(( file_fd = open(&buffer[5],O_RDONLY)) == -1) send_error(500); len = (long)lseek(file_fd, (off_t)0, SEEK_END); lseek(file_fd, (off_t)0, SEEK_SET); sprintf(buffer,"HTTP/1.1 200 OK\nServer: TeaPot\nContent-Length: %ld\nConnection: close\nContent-Type: %s\n\n", len, fstr); write(client_socket, buffer, strlen(buffer)); while ( (ret = read(file_fd, buffer, BUFSIZE)) > 0 ) { (void)write(client_socket,buffer,ret); } sleep(1); close(client_socket); exit(1); }
void *plmc_udp_listener(void *arguments) { int sockfd, msg_length; struct sockaddr_in servaddr, cliaddr; struct in_addr inp; socklen_t addr_length; char mesg[PLMC_MAX_UDP_DATA_LEN]; udp_msg udpmsg; char *match_ip; #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_udp_listener started\n"); fflush(plmc_lib_debug); #endif /* Get the socket */ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { syslog(LOG_ERR, "plmc_lib: encountered an error opening a " "socket"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_DESTROY_LIBRARY, NULL, PLMC_NOOP_CMD); if (pthread_cancel(tcp_listener_id) != 0) { send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_IGNORING, NULL, PLMC_NOOP_CMD); syslog(LOG_ERR, "plmc_lib: encountered an error " "canceling tcp_listener"); } pthread_exit((void *)NULL); } /* * Here we need to register a cleanup function that will be called in * case the UDP listener gets canceled by the library. This is to close * the socket. */ pthread_cleanup_push(udp_listener_cleaner, (void *)&sockfd); match_ip = plmc_get_listening_ip_addr(plmc_config_file); if (strlen(match_ip) == 0) { syslog(LOG_ERR, "plmc_udp_listener cannot match available " "network insterfaces with IPs of controllers " "specified in the plmcd.conf file"); send_error(PLMC_LIBERR_NO_CONF, PLMC_LIBACT_DESTROY_LIBRARY, NULL, PLMC_NOOP_CMD); pthread_exit((void *)NULL); } inet_aton(match_ip, &inp); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inp.s_addr; servaddr.sin_port=htons(atoi(config.udp_broadcast_port)); if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1){ syslog(LOG_ERR, "plmc_lib: encountered an error during a " "call to bind()"); syslog(LOG_ERR, "plmc_lib: errnor is %d", errno); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_DESTROY_LIBRARY, NULL, PLMC_NOOP_CMD); if (pthread_cancel(tcp_listener_id) != 0) { send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_IGNORING, NULL, PLMC_NOOP_CMD); syslog(LOG_ERR, "plmc_lib: encountered an error " "canceling tcp_listener"); } pthread_exit((void *)NULL); } /* We are now entering the while loop. We will hang out here till somebody cancels us */ while (1) { addr_length = sizeof(cliaddr); msg_length = recvfrom(sockfd,mesg,PLMC_MAX_UDP_DATA_LEN, 0,(struct sockaddr *)&cliaddr,&addr_length); mesg[msg_length] = '\0'; #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_udp_listener got a new message: " "%s\n", mesg); fflush(plmc_lib_debug); #endif /* Get the struct setup */ if (parse_udp(&udpmsg, mesg) != 0) { syslog(LOG_ERR, "plmc_lib: UDP message invalid %s", mesg); send_error(PLMC_LIBERR_MSG_INVALID, PLMC_LIBACT_IGNORING, NULL, PLMC_NOOP_CMD); continue; } if ((callbacks.udp_cb(&udpmsg)) != 0) { syslog(LOG_ERR, "plmc_lib: encountered an error " "during the UDP callback call to PLMSv"); send_error(PLMC_LIBERR_ERR_CB, PLMC_LIBACT_IGNORING, udpmsg.ee_id, PLMC_NOOP_CMD); continue; } } /* Remove the cleanup for the connected socket Normally the code will never get here. */ pthread_cleanup_pop(0); }
/* * Now we send over the database. We use the following protocol: * Send over a KRB_SAFE message with the size. Then we send over the * database in blocks of KPROP_BLKSIZE, encrypted using KRB_PRIV. * Then we expect to see a KRB_SAFE message with the size sent back. * * At any point in the protocol, we may send a KRB_ERROR message; this * will abort the entire operation. */ static void xmit_database(krb5_context context, krb5_auth_context auth_context, krb5_creds *my_creds, int fd, int database_fd, int in_database_size) { krb5_int32 n; krb5_data inbuf, outbuf; char buf[KPROP_BUFSIZ]; krb5_error_code retval; krb5_error *error; krb5_ui_4 database_size = in_database_size, send_size, sent_size; /* Send over the size. */ send_size = htonl(database_size); inbuf.data = (char *)&send_size; inbuf.length = sizeof(send_size); /* must be 4, really */ /* KPROP_CKSUMTYPE */ retval = krb5_mk_safe(context, auth_context, &inbuf, &outbuf, NULL); if (retval) { com_err(progname, retval, _("while encoding database size")); send_error(context, my_creds, fd, _("while encoding database size"), retval); exit(1); } retval = krb5_write_message(context, &fd, &outbuf); if (retval) { krb5_free_data_contents(context, &outbuf); com_err(progname, retval, _("while sending database size")); exit(1); } krb5_free_data_contents(context, &outbuf); /* Initialize the initial vector. */ retval = krb5_auth_con_initivector(context, auth_context); if (retval) { send_error(context, my_creds, fd, "failed while initializing i_vector", retval); com_err(progname, retval, _("while allocating i_vector")); exit(1); } /* Send over the file, block by block. */ inbuf.data = buf; sent_size = 0; while ((n = read(database_fd, buf, sizeof(buf)))) { inbuf.length = n; retval = krb5_mk_priv(context, auth_context, &inbuf, &outbuf, NULL); if (retval) { snprintf(buf, sizeof(buf), "while encoding database block starting at %d", sent_size); com_err(progname, retval, "%s", buf); send_error(context, my_creds, fd, buf, retval); exit(1); } retval = krb5_write_message(context, &fd, &outbuf); if (retval) { krb5_free_data_contents(context, &outbuf); com_err(progname, retval, _("while sending database block starting at %d"), sent_size); exit(1); } krb5_free_data_contents(context, &outbuf); sent_size += n; if (debug) printf("%d bytes sent.\n", sent_size); } if (sent_size != database_size) { com_err(progname, 0, _("Premature EOF found for database file!")); send_error(context, my_creds, fd, "Premature EOF found for database file!", KRB5KRB_ERR_GENERIC); exit(1); } /* * OK, we've sent the database; now let's wait for a success * indication from the remote end. */ retval = krb5_read_message(context, &fd, &inbuf); if (retval) { com_err(progname, retval, _("while reading response from server")); exit(1); } /* * If we got an error response back from the server, display * the error message */ if (krb5_is_krb_error(&inbuf)) { retval = krb5_rd_error(context, &inbuf, &error); if (retval) { com_err(progname, retval, _("while decoding error response from server")); exit(1); } if (error->error == KRB_ERR_GENERIC) { if (error->text.data) { fprintf(stderr, _("Generic remote error: %s\n"), error->text.data); } } else if (error->error) { com_err(progname, (krb5_error_code)error->error + ERROR_TABLE_BASE_krb5, _("signalled from server")); if (error->text.data) { fprintf(stderr, _("Error text from server: %s\n"), error->text.data); } } krb5_free_error(context, error); exit(1); } retval = krb5_rd_safe(context,auth_context,&inbuf,&outbuf,NULL); if (retval) { com_err(progname, retval, "while decoding final size packet from server"); exit(1); } memcpy(&send_size, outbuf.data, sizeof(send_size)); send_size = ntohl(send_size); if (send_size != database_size) { com_err(progname, 0, _("Kpropd sent database size %d, expecting %d"), send_size, database_size); exit(1); } free(outbuf.data); }
void *plmc_tcp_listener(void *arguments) { int sockfd, connected, true=1, bytes_received; unsigned int sin_size; struct sockaddr_in servaddr, cliaddr; struct timeval tv; struct in_addr inp; char recv_mesg[PLMC_MAX_TCP_DATA_LEN], *match_ip; pthread_attr_t udp_attr; thread_entry *tentry; int retval = 0; tcp_msg tcpmsg; #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener started\n"); fflush(plmc_lib_debug); #endif /* Set the timeout value for recieve messages from clients */ tv.tv_sec = 2; tv.tv_usec = 0; /* Get the socket */ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { syslog(LOG_ERR, "plmc_lib: encountered an error opening " "a socket"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_DESTROY_LIBRARY, NULL, PLMC_NOOP_CMD); pthread_exit((void *)NULL); } /* Here we need to register a cleanup function that will be called in case the listener gets canceled by the library. This is to close the socket and to cancel all children */ pthread_cleanup_push(tcp_listener_cleaner, (void *)&sockfd); /* Set some socket options, not sure we need this */ if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) < 0) { syslog(LOG_ERR, "plmc_lib: encountered an error during a " "call to setsockopt()"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_IGNORING, NULL, PLMC_NOOP_CMD); } /* Set up the IP stuff */ match_ip = plmc_get_listening_ip_addr(plmc_config_file); if (strlen(match_ip) == 0) { syslog(LOG_ERR, "plmc_tcp_listener cannot match available " "network insterfaces with IPs of controllers " "specified in the plmcd.conf file"); send_error(PLMC_LIBERR_NO_CONF, PLMC_LIBACT_DESTROY_LIBRARY, NULL, PLMC_NOOP_CMD); pthread_exit((void *)NULL); } inet_aton(match_ip, &inp); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(atoi(config.tcp_plms_listening_port)); servaddr.sin_addr.s_addr = inp.s_addr; bzero(&(servaddr.sin_zero),8); /* Socket Address to server */ if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr)) == -1){ syslog(LOG_ERR, "plmc_lib: encountered an error during a " "call to bind()"); syslog(LOG_ERR, "plmc_lib: errnor is %d", errno); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_DESTROY_LIBRARY, NULL, PLMC_NOOP_CMD); close(sockfd); pthread_exit((void *)NULL); } /* Spec max # queued up plmc connections */ if (listen(sockfd, 5) == -1) { syslog(LOG_ERR, "plmc_lib: encountered an error during a call " "to listen()"); syslog(LOG_ERR, "plmc_lib: errnor is %d", errno); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_DESTROY_LIBRARY, NULL, PLMC_NOOP_CMD); close(sockfd); pthread_exit((void *)NULL); } sin_size = sizeof(struct sockaddr_in); /* Set threads detached as we don't want to join them */ pthread_attr_init(&udp_attr); pthread_attr_setdetachstate(&udp_attr, PTHREAD_CREATE_DETACHED); #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener starting the UDP thread\n"); fflush(plmc_lib_debug); #endif /* Create the UDP thread */ if (pthread_create(&(udp_listener_id), &udp_attr, plmc_udp_listener, NULL) != 0) { syslog(LOG_ERR, "plmc_lib: Could not create the UDP thread"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_DESTROY_LIBRARY, NULL, PLMC_NOOP_CMD); close(sockfd); pthread_exit((void *)NULL); } /* * This is the while loop that will take in new connections and * start client_mgr threads that deal with those connections. */ while (1) { #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener entering the while " "loop\n"); fflush(plmc_lib_debug); #endif connected = accept(sockfd, (struct sockaddr *)&cliaddr, &sin_size); #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener got a new " "connection\n"); fflush(plmc_lib_debug); #endif if (connected < 0) { syslog(LOG_ERR, "plmc_lib: encoutered a problem in " "the accept() call"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_IGNORING, NULL, PLMC_NOOP_CMD); continue; } /* * Push another cleanup function as we have opened a new * socket (connected) and have not yet handed it over to a child * thread (client_mgr). If we get canceled here we need to close * that socket. */ pthread_cleanup_push(client_mgr_cleaner, (void *)&connected); /* Set the timeout SO_RCVTIMEO for the new socket This so a client can't hang the listener for too long */ if (setsockopt (connected, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv) < 0) { syslog(LOG_ERR, "plmc_lib: encountered an error during " "a call to setsockopt()"); syslog(LOG_ERR, "plmc_lib: errnor is %d", errno); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_CLOSE_SOCKET, NULL, PLMC_NOOP_CMD); if (close_socket(connected) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an " "error during a call to close_socket"); } continue; } #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener sending a request " "for the ee_id\n"); fflush(plmc_lib_debug); #endif /* Send a request for the ee_id to the client */ retval = send(connected, PLMC_cmd_name[PLMC_GET_ID_CMD], strlen(PLMC_cmd_name[PLMC_GET_ID_CMD]), 0); if (retval < 0) { syslog(LOG_ERR, "plmc_lib: encountered an error " "during a call to send()"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_CLOSE_SOCKET, NULL, PLMC_GET_ID_CMD); if (close_socket(connected) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an " "error during a call to close_socket"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_CLOSE_SOCKET, NULL, PLMC_GET_ID_CMD); } continue; } /* Now wait for the response for tv time */ bytes_received = recv(connected, recv_mesg, PLMC_MAX_TCP_DATA_LEN, 0); if (bytes_received < 0 ){ /* The client didn't come back in time. Can't hang around waiting for this guy. Close this socket. He'll just have to reconnect */ syslog(LOG_ERR, "plmc_lib: The client is taking too " "long to respond, closing socket"); send_error(PLMC_LIBERR_TIMEOUT, PLMC_LIBACT_CLOSE_SOCKET, NULL, PLMC_GET_ID_CMD); if (close_socket(connected) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an " "error during a call to close_socket"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_CLOSE_SOCKET, NULL, PLMC_GET_ID_CMD); } continue; } recv_mesg[bytes_received] = '\0'; #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener got response back: " "%s\n", recv_mesg); fflush(plmc_lib_debug); #endif if (parse_tcp(&tcpmsg, recv_mesg) != 0) { syslog(LOG_ERR, "plmc_lib: Invalid TCP message " "during GET_EE_ID"); send_error(PLMC_LIBERR_MSG_INVALID, PLMC_LIBACT_CLOSE_SOCKET, NULL, PLMC_GET_ID_CMD); if (close_socket(connected) !=0) { syslog(LOG_ERR, "plmc_lib: encountered an " "error during a call to close_socket"); } continue; } #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener creating thread " "entry with ee_id %s and socket %d\n", tcpmsg.ee_id, connected); fflush(plmc_lib_debug); #endif /* Create the thread_entry - This is thread safe */ tentry = create_thread_entry(tcpmsg.ee_id, connected); if (tentry == NULL) { #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener found an " "entry that has to be closed, " "closing socket on current client\n"); fflush(plmc_lib_debug); #endif close_socket(connected); } else { #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_tcp_listener didn't " "find an entry that has to be closed. " "We can reuse this entry\n"); fflush(plmc_lib_debug); #endif if ((callbacks.connect_cb(tcpmsg.ee_id, PLMC_CONN_CB_MSG)) != 0) { send_error(PLMC_LIBERR_ERR_CB, PLMC_LIBACT_IGNORING, tcpmsg.ee_id, PLMC_GET_ID_CMD); } } /* * Remove the cleanup for the connected socket as we don't care * about that anymore. This socket is now handled by the * client_mgr and this guy will close it if it is canceled */ pthread_cleanup_pop(0); } pthread_cleanup_pop(1); pthread_exit((void *)NULL); }
static gboolean handle_message (InsanityGstPipelineTest * ptest, GstMessage * message) { gboolean ret = FALSE, done = FALSE; /* Allow the test code to handle the message instead */ g_signal_emit (ptest, bus_message_signal, 0, message, &ret); if (!ret) return FALSE; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR:{ GError *error = NULL; char *debug = NULL; gst_message_parse_error (message, &error, &debug); send_error (ptest, error, debug); insanity_test_printf (INSANITY_TEST (ptest), "Error (%s, %s), quitting\n", error->message, debug); g_error_free (error); g_free (debug); done = TRUE; break; } case GST_MESSAGE_STATE_CHANGED: if (GST_MESSAGE_SRC (message) == GST_OBJECT (ptest->priv->pipeline)) { GstState oldstate, newstate, pending; gst_message_parse_state_changed (message, &oldstate, &newstate, &pending); if (newstate >= GST_STATE_PAUSED) { gint i; for (i = 0; i < G_N_ELEMENTS (duration_query_formats); i++) insanity_gst_pipeline_test_query_duration (ptest, duration_query_formats[i], NULL); } if (newstate == ptest->priv->initial_state && pending == GST_STATE_VOID_PENDING && !ptest->priv->reached_initial_state) { gboolean ret = TRUE; ptest->priv->reached_initial_state = TRUE; insanity_test_validate_checklist_item (INSANITY_TEST (ptest), "reached-initial-state", TRUE, NULL); /* Tell the test we reached our initial state */ g_signal_emit (ptest, reached_initial_state_signal, 0, &ret); if (!ret) { insanity_test_printf (INSANITY_TEST (ptest), "Reached initial state, and asked to quit, quitting\n"); done = TRUE; } } } break; case GST_MESSAGE_TAG:{ GstTagList *tags; gst_message_parse_tag (message, &tags); gst_tag_list_foreach (tags, &send_tag, (gpointer) ptest); gst_tag_list_unref (tags); break; } case GST_MESSAGE_DURATION_CHANGED:{ gint i; for (i = 0; i < G_N_ELEMENTS (duration_query_formats); i++) insanity_gst_pipeline_test_query_duration (ptest, duration_query_formats[i], NULL); break; } case GST_MESSAGE_EOS: if (GST_MESSAGE_SRC (message) == GST_OBJECT (ptest->priv->pipeline)) { /* Warning from the original Python source: # it's not 100% sure we want to stop here, because of the # race between the final state-change message and the eos message # arriving on the bus. */ if (ptest->priv->reached_initial_state) { insanity_test_printf (INSANITY_TEST (ptest), "Got EOS from pipeline, and we reached initial state, quitting\n"); done = TRUE; } else { /* If we've not seen the state change to initial state yet, we give an extra 3 seconds for it to complete */ insanity_test_printf (INSANITY_TEST (ptest), "Got EOS from pipeline, and we did not reach initial state, delaying quit\n"); ptest->priv->wait_timeout_id = g_timeout_add (3000, (GSourceFunc) & waiting_for_state_change, ptest); } } break; case GST_MESSAGE_BUFFERING:{ gint percent; gst_message_parse_buffering (message, &percent); /* no state management needed for live pipelines */ if (ptest->priv->is_live || !ptest->priv->enable_buffering) break; if (percent == 100) { /* a 100% message means buffering is done */ ptest->priv->buffering = FALSE; /* if the desired state is playing, go back */ if (ptest->priv->initial_state == GST_STATE_PLAYING) { gst_element_set_state (GST_ELEMENT (ptest->priv->pipeline), GST_STATE_PLAYING); } } else { /* buffering busy */ if (ptest->priv->buffering == FALSE && ptest->priv->initial_state == GST_STATE_PLAYING) { /* we were not buffering but PLAYING, PAUSE the pipeline. */ gst_element_set_state (GST_ELEMENT (ptest->priv->pipeline), GST_STATE_PAUSED); } ptest->priv->buffering = TRUE; } break; case GST_MESSAGE_CLOCK_LOST: gst_element_set_state (GST_ELEMENT (ptest->priv->pipeline), GST_STATE_PAUSED); gst_element_set_state (GST_ELEMENT (ptest->priv->pipeline), GST_STATE_PLAYING); break; } default: break; } return done; }
/********************************************************************** * plmc_connection_mgr - This is the thread that is responsible for * monitoring all the connections * This guy will periodically wakeup, walk through the list * and ping all the plmc clients. If they are not anymore available * plmc_connection_mgr will delete the entry and kill off any thread * that is talking to them * * Parameters: * No parameters * * Returns: * This function returns a *void ***********************************************************************/ void *plmc_connection_mgr(void *arguments) { thread_entry *tentry; thread_data *tdata; char result[PLMC_MAX_TCP_DATA_LEN]; pthread_t plmc_client_mgr_id; PLMC_cmd_idx cmd_enum; int sockfd, o_state, kill; pthread_cleanup_push(connection_mgr_cleaner, NULL); #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_connection_mgr started up\n"); fflush(plmc_lib_debug); #endif while (1) { /* Start by sleeping 5 seconds */ sleep(5); /* Perhaps a definition in a header file */ tentry = HEAD; while(tentry != NULL) { /* Do not allow to be canceled */ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &o_state); /* Lock to get the socket */ if (pthread_mutex_lock(&tentry->thread_d.td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: " "plmc_connection_mgr encountered an " "error getting a lock for a client"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_IGNORING, NULL, PLMC_NOOP_CMD); break; } tdata = &(tentry->thread_d); sockfd = tdata->socketfd; plmc_client_mgr_id = tdata->td_id; kill = tdata->kill; if(tdata->done == 0) { cmd_enum = plmc_cmd_string_to_enum( tdata->command); if (cmd_enum < 0) cmd_enum = PLMC_NOOP_CMD; } else { cmd_enum = PLMC_NOOP_CMD; } if (sockfd != 0 && recv(sockfd, result, PLMC_MAX_TCP_DATA_LEN, MSG_PEEK | MSG_DONTWAIT) == 0) { kill = 1; #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_connection_mgr: " "Discovered a client that didn't " "answer. Setting kill = 1. EE_ID is " "%s\n", tdata->ee_id); fflush(plmc_lib_debug); #endif } /* Check if kill is 1. If it is it means we potentially * need to kill the client and close the socket */ if (kill == 1) { #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_connection_mgr: " "Kill is set to 1. Cleaning up " "for EE_ID %s\n", tdata->ee_id); fflush(plmc_lib_debug); #endif /* * If the client_mgr thread is running, * kill him */ if (plmc_client_mgr_id != 0) { #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_connection_mgr: Client " "mgr is running. We will need " "to kill him. EE_ID is %s\n", tdata->ee_id); fflush(plmc_lib_debug); #endif if (pthread_cancel(plmc_client_mgr_id) != 0) { syslog(LOG_ERR, "plmc_lib: " "encountered an error " "trying to cancel a " "client mgr thread"); } } if (sockfd != 0) { send_error(PLMC_LIBERR_LOST_CONNECTION, PLMC_LIBACT_CLOSE_SOCKET, tdata->ee_id, cmd_enum); #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_connection_mgr: We are " "closing the socket. EE_ID is " "%s\n", tdata->ee_id); fflush(plmc_lib_debug); #endif /* Now, close the socket */ close_socket(sockfd); if ((callbacks.connect_cb(tdata->ee_id, PLMC_DISCONN_CB_MSG)) != 0) { syslog(LOG_ERR, "plmc_lib: " "encountered an error " "during the disconnect " "callback"); } } tdata->socketfd = 0; tdata->td_id = 0; tdata->kill = 0; tdata->done = 1; } /* * Ok, time to unlock */ if (pthread_mutex_unlock(&tdata->td_lock) != 0) { syslog(LOG_ERR, "plmc_lib: encountered an " "error unlocking a client mutex"); send_error(PLMC_LIBERR_SYSTEM_RESOURCES, PLMC_LIBACT_UNDEFINED, tdata->ee_id, cmd_enum); } /* Allow to be canceled again */ pthread_setcancelstate(o_state, &o_state); tentry = tentry->next; } } #ifdef PLMC_LIB_DEBUG fprintf(plmc_lib_debug, "plmc_connection_mgr: I am exiting\n"); fflush(plmc_lib_debug); #endif pthread_cleanup_pop(0); pthread_exit((void *)NULL); }