balboa_core *balboa_get_core(balboa *b, const char *corename) { char buf[1024]; int ret; long long window, size; balboa_core *c = calloc(sizeof *c, 1); char name[1024], devpath[1024]; if (!c) { snprintf(errbuf, sizeof errbuf, "calloc failed"); return 0; } snprintf(buf, sizeof buf, "core %s", corename); ret = daemon_send(b->daemon_fd, buf); if (ret == 0) return 0; ret = daemon_recv(b->daemon_fd, buf, sizeof buf); if (ret == 0) return 0; ret = sscanf(buf, "ok core %1023s mem %1023s 0x%llx size 0x%llx", name, devpath, &window, &size); if (ret != 4) { snprintf(errbuf, sizeof errbuf, "Bad response to 'core': '%s'", buf); return 0; } c->devpath = strdup(devpath); c->window = window; c->mem_size = size; return c; }
static daemon_reply _lvmlockd_send(const char *req_name, ...) { va_list ap; daemon_reply repl; daemon_request req; req = daemon_request_make(req_name); va_start(ap, req_name); daemon_request_extend_v(req, ap); va_end(ap); repl = daemon_send(_lvmlockd, req); daemon_request_destroy(req); return repl; }
static int get_socket(const char *port) { int fd, ret; char buf[100]; int bufsz = sizeof(buf); struct sockaddr_un sa; int socklen; fd = socket(AF_LOCAL, SOCK_STREAM, 0); if (fd == -1) { snprintf(errbuf, sizeof(errbuf), "socket: %s", strerror(errno)); return -1; } memset(&sa, 0, sizeof(sa)); sa.sun_family = AF_UNIX; strcpy(sa.sun_path, port); socklen = offsetof(struct sockaddr_un, sun_path) + strlen(port) + 1; ret = connect(fd, (struct sockaddr *)&sa, socklen); if (ret == -1) { snprintf(errbuf, sizeof(errbuf), "connect: %s", strerror(errno)); goto fail; } ret = daemon_send(fd, "hi"); if (ret == 0) goto fail; ret = daemon_recv(fd, buf, bufsz); if (ret == 0) goto fail; if (strcmp(buf, "ok\n")) { snprintf(errbuf, sizeof(errbuf), "protocol error, got '%s'", buf); goto fail; } return fd; fail: close(fd); return -1; }
void* daemon_request_neighbourhood (void *arg) { struct daemon_request *r; struct daemon *tmp; char answer[25]; // FIXME : LOLZ r = (struct daemon_request *) arg; if (!r) return NULL; sem_wait (&daemons_lock); for_each_daemon (tmp) { if (strcmp (r->daemon->addr, tmp->addr) != 0) { sprintf (answer, "neighbour %s:%d\n", tmp->addr, tmp->port); daemon_send (r->daemon, answer); } } sem_post (&daemons_lock); return NULL; }
static void * handle_requests (struct daemon *daemon) { /* The message typed by the user */ char *message = NULL; struct daemon_request *r; struct pool *pool; void* (*handler) (void *); for (;;) { message = socket_getline (daemon->socket); if (!message) break; /* Only request we're allowed to treat no matter how many requests are * currently being treated */ if (strncmp (message, "quit", 4) == 0) break; sem_wait (&daemon->req_lock); if (daemon->nb_requests == prefs->max_requests_per_daemon) { sem_post (&daemon->req_lock); /* FIXME: this is copy-paste from client, should be different */ daemon_send (daemon, " < Too many requests, mister, plz calm down\n"); continue; } sem_post (&daemon->req_lock); /* Treating all the common requests */ /* FIXME : use the IS_CMD macro */ pool = fast_pool; #if 0 if (strncmp (message, "list", 4) == 0) { pool = slow_pool; handler = daemon_request_list; } else if (strncmp (message, "get", 3) == 0) handler = daemon_request_get; else if (strncmp (message, "file", 4) == 0) handler = daemon_request_file; else if (strncmp (message, "neighbourhood", 13) == 0) handler = daemon_request_neighbourhood; else if (strncmp (message, "neighbour", 9) == 0) handler = daemon_request_neighbour; else if (strncmp (message, "ready", 5) == 0) handler = daemon_request_ready; #endif if (IS_CMD (message, "list")) { pool = slow_pool; handler = &daemon_request_list; } else if (IS_CMD (message, "get")) handler = &daemon_request_get; else if (IS_CMD (message, "file")) handler = &daemon_request_file; else if (IS_CMD (message, "neighbourhood")) handler = &daemon_request_neighbourhood; else if (IS_CMD (message, "neighbour")) handler = &daemon_request_neighbour; else if (IS_CMD (message, "ready")) handler = &daemon_request_ready; else handler = daemon_request_unknown; r = daemon_request_new (message, daemon, pool, handler); if (!r) { daemon_send (daemon, " < Failed to create a new request\n"); continue; } sem_wait (&daemon->req_lock); daemon->requests = daemon_request_add (daemon->requests, r); if (!daemon->requests) { daemon_request_free (r); break; } sem_post (&daemon->req_lock); pool_queue (r->pool, daemon_request_handler, r); } if (message) free (message); return NULL; }
void* daemon_request_file (void* arg) { struct daemon_request *r; struct parsed_cmd *pcmd; struct client *lister; char error_buffer[BUFFSIZE]; r = (struct daemon_request *) arg; if (!r) return NULL; /* * First, did someone asked "list"? */ lister = list_client; if (!lister) return NULL; /* * cmd is supposedly: * file NAME KEY SIZE IP:PORT * 0 1 2 3 4 */ if (cmd_parse_failed ((pcmd = cmd_parse (r->cmd, NULL)))) { sprintf (error_buffer, "error %s: Command parse failed", __FUNCTION__); daemon_send (r->daemon, error_buffer); return NULL; } if (pcmd->argc < 5) { cmd_parse_free (pcmd); sprintf (error_buffer, "error %s: Invalid number of arguments", __FUNCTION__); daemon_send (r->daemon, error_buffer); return NULL; } /* * Hackety hack: * IP:PORT\0 -> IP\0PORT\0 */ char *port = strchr (pcmd->argv[4], ':'); *port = '\0'; port++; file_cache = file_cache_add (file_cache, pcmd->argv[1], pcmd->argv[2], atol (pcmd->argv[3]), pcmd->argv[4], atoi (port)); cmd_parse_free (pcmd); char *answer = (char *)malloc ((strlen (r->cmd) + 5) * sizeof (char)); sprintf (answer, " < %s\n", r->cmd); client_send (lister, answer); free (answer); return NULL; }
void* client_request_get (void *arg) { r = (struct client_request *) arg; struct daemon_list *d_list; struct daemon_list *list_item_to_delete; struct daemon *next_d; int seeder_count; if (!r) return NULL; /* First we find the file in the cache */ if (find_file () < 0) return NULL; /* file_to_dl should now be the good one */ /* Find the daemons owning the file by checking its IP */ if ((d_list = find_daemons ()) != NULL) { if (client_send (r->client, " < no seeder for the requested file. Former seeders must have been disconnected.\n") < 0) log_failure (log_file, "cr_get: client_send () failed"); return NULL; } /* about handling multi-seeders and block-by-block download */ // we know the number of seeders seeder_count = d_list->id; /* FIXME : calculate smartly the blocks to consider, * given : * - number of seeders * - size of file to dl * - a max_size for a block ? Not implemented */ /* loop where we have to post a job for each seeder */ next_d = d_list->daemon; while (next_d != NULL) { // FIXME : act !!!! do something !!! list_item_to_delete = d_list; d_list = d_list->next; free (list_item_to_delete); } /* Sending the "get key begin end" message */ sprintf (answer, "get %s %d %ld\n", file_to_dl->key, 0, file_to_dl->size); if (daemon_send (d, answer) < 0) { log_failure (log_file, "cr_get: could not send the get command"); return NULL; } /* FIXME */ #if 0 sem_wait (&downloads_lock); char *full_path; struct dl_file *f; full_path = malloc (strlen (prefs->shared_folder) + strlen (file_to_dl->filename) + 2); if (!full_path) { log_failure (log_file, "OMG NO MALLOC IS POSSIBLE"); return NULL; } else { sprintf (full_path, "%s/%s", prefs->shared_folder, file_to_dl->filename); } f = dl_file_new (full_path); if (!f) { log_failure (log_file, "SHARED FOLDER : %S", prefs->shared_folder); log_failure (log_file, "f was NULL %s", full_path); } downloads = dl_file_add (downloads, f); if (!downloads) log_failure (log_file, "downlaods was NULL"); else log_failure (log_file, "downloads->path : %s", downloads->path); sem_post (&downloads_lock); #endif return NULL; }
void* daemon_request_ready (void* arg) { struct daemon_request *r; // Parse elements char *key, *delay, *ip, *port, *proto, *begin, *end; /* cmd version: */ int argc; char **argv; int dl_sock; struct sockaddr_in dl_addr; struct file_cache *file; int local_file; int nb_received; file_size_t nb_received_sum; char buffer[BUFFSIZE]; int nb_written; char *full_path; char error_buffer[BUFFSIZE]; r = (struct daemon_request *) arg; if (!r) return NULL; /* * cmd is supposedly: * ready KEY DELAY IP PORT PROTOCOL BEGINNING END */ argv = cmd_to_argc_argv (r->cmd, &argc); if (argc < 8) { cmd_free (argv); sprintf (error_buffer, "error %s: Invalid number of arguments", __FUNCTION__); daemon_send (r->daemon, error_buffer); return NULL; } key = argv[1]; delay = argv[2]; ip = argv[3]; port = argv[4]; proto = argv[5]; begin = argv[6]; end = argv[7]; /* TODO&FIXME: We should use all above arguments */ if ((dl_sock = socket (AF_INET, SOCK_STREAM, 0)) < 0) { log_failure (log_file, "daemon_request_ready (): socket () failed"); return NULL; } dl_addr.sin_family = AF_INET; if (inet_pton (AF_INET, ip, &dl_addr.sin_addr) < 1) { log_failure (log_file, "dr_ready: inet_pton () failed"); return NULL; } // TODO: Verifications on port dl_addr.sin_port = htons (atoi (port)); file = file_cache_get_by_key (file_cache, key); if (!file) { log_failure (log_file, "dr_ready: file_cache_get_by_key () failed"); return NULL; } // TODO: Check if we actually asked for that file // TODO: Check if file already exists /* + 2 for '/' and '\0' */ full_path = (char *)malloc ((strlen (prefs->shared_folder) + strlen (file->filename) + 2) * sizeof (char)); sprintf (full_path, "%s/%s", prefs->shared_folder, file->filename); // FIXME: We should not truncate the file when downloading it by blocks local_file = open (full_path, O_WRONLY | O_TRUNC | O_CREAT, (mode_t)0644); //free (full_path); if (local_file < 0) { log_failure (log_file, "dr_ready: open () failed, error: %s", strerror (errno)); return NULL; } if (connect (dl_sock, (struct sockaddr *)&dl_addr, sizeof (dl_addr)) < 0) { log_failure (log_file, "dr_ready: connect () failed, error: %s", strerror (errno)); return NULL; } /* * Downloading the file */ /* Let's upload the download queue */ struct dl_file *f; f = dl_file_new (full_path, file->size); if (!f) { log_failure (log_file, "struct dl_file is NULL :("); goto out; } sem_wait (&downloads_lock); downloads = dl_file_add (downloads, f); if (!downloads) { log_failure (log_file, "Could not add the file to the download queue\n"); goto out; } sem_post (&downloads_lock); nb_received_sum = 0; // FIXME: nb_received_sum should be compared to end - begin sleep (2); while (nb_received_sum < file->size) { log_failure (log_file, "DBG %d %d", nb_received_sum, file->size); nb_received = recv (dl_sock, buffer, BUFFSIZE, 0); if (nb_received < 0) { log_failure (log_file, "dr_ready: recv () failed"); return NULL; } nb_received_sum += nb_received; while (nb_received) { nb_written = write (local_file, buffer, nb_received); if (nb_written < 0) { log_failure (log_file, "dr_ready: write () failed"); return NULL; } nb_received -= nb_written; } } /* * Releasing the file from the download queue */ sem_wait (&downloads_lock); downloads = dl_file_remove (downloads, f); dl_file_free (f); sem_post (&downloads_lock); log_success (log_file, "dr_ready: Received block completely %s", full_path); close (dl_sock); close (local_file); out: if (full_path) free (full_path); if (argv) cmd_free (argv); return NULL; }
/* do the startup work for your module, returns 0 if startup ok, else if error. this is a very special function, we can do normal send and recv in this function, since the module is still in status INIT now. normally, send & recv should be done by daemon thread. */ int mc703_module_startup(IDEV *p) { /* 流程: 1: ATE0 2: ATV1 3: AT^PREFMODE=8 4: AT+CPIN? ----> OK 5: sleep(5); 6: AT+CSQ ----> +CSQ: 31,99 7: AT+CPMS="SM","SM","SM" 8: AT^HSMSSS=0,0,1,0 9: AT+CNMI=1,1,0,1,0 10: AT+CMGF=1 11: AT^PPPCFG="*****@*****.**","vnet.mobi" */ int result; char buf[256]; char *pTmp; result = daemon_send(p, "ATE0", buf); if (result) return -2; if (!strstr(buf, "OK")) return -1; result = daemon_send(p, "ATV1", buf); if (result) return -2; /* wait for some time to get the OK */ sleep(3); /* just read */ result = daemon_send(p, "AT", buf); if (result) return -2; if (!strstr(buf, "OK")) return -1; result = daemon_send(p, "AT^PREFMODE=8", buf); if (result) return -2; if (!strstr(buf, "OK")) return -1; result = daemon_send(p, "AT+CPIN?", buf); if (result) return -2; if (!strstr(buf, "OK")) return -1; // wait for checking network sleep(5); while(1) { result = daemon_send(p, "AT+CSQ", buf); if (result) return -2; if ((pTmp = strstr(buf, "+CSQ:"))) { sscanf(pTmp, "+CSQ:%d", &result); if (result != 99) { break; } else { printf("Waiting to register(%d): %s", result, pTmp); sleep(3); } break; } } // sleep(3); // daemon_flush(p); result = daemon_send(p, "AT+CPMS=\"SM\",\"SM\",\"SM\"", buf); if (result) return -2; /* CPMS return 2 times, just skip this first */ // if (!strstr(buf, "OK")) // return -1; result = daemon_send(p, "AT^HSMSSS=0,0,1,0", buf); if (result) return -2; if (!strstr(buf, "OK")) return -1; result = daemon_send(p, "AT+CNMI=1,1,0,1,0", buf); if (result) return -2; if (!strstr(buf, "OK")) return -1; result = daemon_send(p, "AT+CMGF=1", buf); if (result) return -2; if (!strstr(buf, "OK")) return -1; result = daemon_send(p, "AT^PPPCFG=\"[email protected]\",\"vnet.mobi\"", buf); if (result) return -2; if (!strstr(buf, "OK")) return -1; daemon_flush(p); return 0; }
static void server_stop (int sig) { struct client *c; struct daemon *d; pool_destroy (slow_pool); pool_destroy (fast_pool); pool_destroy (clients_pool); pool_destroy (daemons_pool); (void) sig; log_failure (log_file, "Ok, received a signal"); sleep (2); sem_destroy (&clients_lock); sem_destroy (&daemons_lock); sem_destroy (&file_cache_lock); sem_destroy (&downloads_lock); if (clients) { while (clients) { c = clients->next; client_free (clients); clients = c; } log_success (log_file, "%s : all clients have been freed", __func__); } if (daemons) { while (daemons) { d = daemons->next; daemon_send (daemons, "quit\n"); daemon_free (daemons); daemons = d; } log_success (log_file, "%s : all daemons have been freed", __func__); } if (file_cache) { file_cache_free (file_cache); log_success (log_file, "%s : file cache has been freed", __func__); } if (unlink (prefs->lock_file) < 0) if (log_file) log_failure (log_file, "Could not destroy the lock file"); if (prefs) { conf_free (prefs); log_success (log_file, "%s : Preferences have been freed.", __func__); } if (log_file) { log_success (log_file, "Stopping server, waiting for SIGKILL"); fclose (log_file); } exit (EXIT_SUCCESS); }
void* daemon_request_list (void *arg) { struct daemon_request *r; char answer[512]; DIR *dir; struct dirent *entry; char entry_full_path[256]; struct stat entry_stat; char *key; /* OKAY, let's say all options/args are silently ignored */ r = (struct daemon_request *)arg; if (!r) return NULL; dir = opendir (prefs->shared_folder); if (dir == NULL) { log_failure (log_file, "daemon_request_list (): Unable to opendir %s", prefs->shared_folder); return NULL; } // Browsing my own files for (entry = readdir (dir); entry != NULL; entry = readdir (dir)) { // Listing all regular files if (entry->d_type == DT_REG) { sprintf (entry_full_path, "%s/%s", prefs->shared_folder, entry->d_name); if (stat (entry_full_path, &entry_stat) < 0) { log_failure (log_file, "daemon_request_list (): can't stat file %s", entry_full_path); continue; } key = get_md5 (entry_full_path); if (!key) continue; sprintf (answer, "file %s %s %d %s:%d\n", entry->d_name, key, (int) entry_stat.st_size, my_ip, prefs->daemon_port); if (daemon_send (r->daemon, answer) < 0) { log_failure (log_file, "daemon_request_list (): failed to send data to daemon"); } free (key); key = NULL; } } if (closedir (dir) < 0) { log_failure (log_file, "daemon_request_list () : can't close shared directory"); return NULL; } return NULL; }