static int client_upload(int sock, char *file_path) { assert(file_path != NULL); assert(sock >= 0); ldebug("upload file(%s), please wait a moment...", file_path); int file_size = 0; int total_len = 0; struct trans_data_t *ptrans = NULL; if (-1 == get_file_size(file_path, &file_size)) { lerror("call get_file_size() failed"); goto ERR; } if (!file_size) { lwarn("file is null, file_path: %s", file_path); goto ERR; } total_len = sizeof(struct trans_data_t) + file_size; ptrans = (struct trans_data_t *)calloc(1, total_len); if (NULL == ptrans) { lerror("malloc memory failed, err:%s", strerror(errno)); abort(); } ptrans->cmd = UD_UPLOAD; ptrans->data_len = file_size; snprintf(ptrans->filename, MAX_FILE_NAME_LENGTH-1, "%s", basename(file_path)); ptrans->filename[MAX_FILE_NAME_LENGTH - 1] = '0'; if (-1 == read_file(ptrans, file_path)) { lerror("call read_data() failed, file_path: %s", file_path); } if (-1 == send_data(sock, ptrans, get_trans_data_t_size(ptrans))) { lerror("call send_data() failed, sock: %d, data_len: %d", sock, ptrans->data_len); return -1; } ldebug("upload file success"); return 0; ERR: lwarn("upload file failed"); if (ptrans != NULL) { free(ptrans); } return -1; }
etype etype::operator/(const etype &var) { switch(type){ case ET_INT: return(etype( *(int*)value / var.i() )); case ET_FLOAT: return(etype( *(float*)value / var.f() )); case ET_DOUBLE: return(etype( *(double*)value / var.d() )); case ET_CHAR: return(etype( *(char*)value / var.c() )); case ET_ESTR: lwarn("division not defined for string type"); return(estr()); case ET_EARRAY: lwarn("division not defined for array type"); return(estrarray()); } lwarn("undefined value"); return(estr()); }
int ipc_accept(void) { struct sockaddr_un saun; socklen_t slen = sizeof(struct sockaddr_un); if (ipc_sock != -1) { lwarn("New connection inbound when one already exists. Dropping old"); close(ipc_sock); } ipc_sock = accept(listen_sock, (struct sockaddr *)&saun, &slen); if (ipc_sock < 0) { lerr("Failed to accept() from listen_sock (%d): %s", listen_sock, strerror(errno)); return -1; } /* reset the ipc event counter for each session */ memset(&ipc_events, 0, sizeof(ipc_events)); gettimeofday(&ipc_events.start, NULL); set_socket_buffers(ipc_sock); return ipc_sock; }
/* daemon-specific node manipulation */ static void post_process_nodes(void) { uint i, x; ldebug("post processing %d masters, %d pollers, %d peers", num_masters, num_pollers, num_peers); for (i = 0; i < num_nodes; i++) { merlin_node *node = node_table[i]; if (!node) { lerr("node is null. i is %d. num_nodes is %d. wtf?", i, num_nodes); continue; } if (!node->sain.sin_port) node->sain.sin_port = htons(default_port); node->action = node_action_handler; node->ioc = iocache_create(MERLIN_IOC_BUFSIZE); if (node->ioc == NULL) { lerr("Failed to malloc(%i) for io cache for node %s. Aborting", MERLIN_IOC_BUFSIZE, node->name); } /* * this lets us support multiple merlin instances on * a single system, but all instances on the same * system will be marked at the same time, so we skip * them on the second pass here. */ if (node->flags & MERLIN_NODE_FIXED_SRCPORT) { continue; } if (node->sain.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) { node->flags |= MERLIN_NODE_FIXED_SRCPORT; ldebug("Using fixed source-port for local %s node %s", node_type(node), node->name); continue; } for (x = i + 1; x < num_nodes; x++) { merlin_node *nx = node_table[x]; if (node->sain.sin_addr.s_addr == nx->sain.sin_addr.s_addr) { ldebug("Using fixed source-port for %s node %s", node_type(node), node->name); ldebug("Using fixed source-port for %s node %s", node_type(nx), nx->name); node->flags |= MERLIN_NODE_FIXED_SRCPORT; nx->flags |= MERLIN_NODE_FIXED_SRCPORT; if (node->sain.sin_port == nx->sain.sin_port) { lwarn("Nodes %s and %s have same ip *and* same port. Voodoo?", node->name, nx->name); } } } } }
static merlin_node *find_node(struct sockaddr_in *sain) { uint i; merlin_node *first = NULL; if (!sain) return NULL; for (i = 0; i < num_nodes; i++) { merlin_node *node = node_table[i]; unsigned short source_port = ntohs(sain->sin_port); unsigned short in_port = net_source_port(node); ldebug("FINDNODE: node->sain.sin_addr.s_addr: %d", node->sain.sin_addr.s_addr); if (node->sain.sin_addr.s_addr == sain->sin_addr.s_addr) { if (source_port == in_port) { /* perfect match */ ldebug("Inbound connection matches %s exactly (%s:%d)", node->name, inet_ntoa(sain->sin_addr), in_port); return node; } if (!first && !(node->flags & MERLIN_NODE_FIXED_SRCPORT)) first = node; } } if (first) { lwarn("Inbound connection presumably from %s (%s:%d != %s:%d)", first->name, inet_ntoa(sain->sin_addr), ntohs(sain->sin_port), inet_ntoa(first->sain.sin_addr), net_source_port(first)); } return first; }
static int process_download(int sock, struct trans_data_t *ptrans) { assert(ptrans != NULL); char file_path[MAX_FILE_PATH_LENGTH] = { '\0' }; snprintf(file_path, MAX_FILE_PATH_LENGTH-1, "%s%s", STORE_SERVER_DATA_PATH, ptrans->filename); file_path[MAX_FILE_PATH_LENGTH-1] = '\0'; if (-1 == get_file_size(file_path, &(ptrans->data_len))) { lwarn("call get_fail_size failed failed"); goto FAIL; } ldebug("be called, filename: %s, size: %d", ptrans->filename, ptrans->data_len); if (-1 == read_file(ptrans, file_path)) { lerror("read file failed, file_path: %s", file_path); goto FAIL; } if (-1 == send_data(sock, ptrans, get_trans_data_t_size(ptrans))) { lerror("send data failed, sock: %d, data_len: %d", sock, ptrans->data_len); goto ERR; } return 0; FAIL: assert(0); //TODO:未完成 return -1; ERR: return -1; }
/* * import objects and status from objects.cache and status.log, * respecively */ static int import_objects_and_status(char *cfg, char *cache, char *status) { char *cmd; int result = 0; /* don't bother if we're not using a datbase */ if (!use_database) return 0; /* ... or if an import is already in progress */ if (importer_pid) { lwarn("Import already in progress. Ignoring import event"); return 0; } if (!import_program) { lerr("No import program specified. Ignoring import event"); return 0; } asprintf(&cmd, "%s --nagios-cfg='%s' " "--db-type='%s' --db-name='%s' --db-user='******' --db-pass='******' --db-host='%s' --db-conn_str='%s'", import_program, cfg, sql_db_type(), sql_db_name(), sql_db_user(), sql_db_pass(), sql_db_host(), sql_db_conn_str()); if (cache && *cache) { char *cmd2 = cmd; asprintf(&cmd, "%s --cache='%s'", cmd2, cache); free(cmd2); if (db_track_current && status && *status) { cmd2 = cmd; asprintf(&cmd, "%s --status-log='%s'", cmd2, status); free(cmd2); } } if (sql_db_port()) { char *cmd2 = cmd; asprintf(&cmd, "%s --db-port='%u'", cmd2, sql_db_port()); free(cmd2); } run_program("import", cmd, &importer_pid); free(cmd); /* * If the import program started successfully, we * ask the module to stall events until it's done */ if (importer_pid > 0) { ipc_send_ctrl(CTRL_STALL, CTRL_GENERIC); } return result; }
/* * Handles merlin control events inside the module. Control events * that relate to cross-host communication only never reaches this. */ void handle_control(merlin_node *node, merlin_event *pkt) { const char *ctrl; if (!pkt) { lerr("handle_control() called with NULL packet"); return; } ctrl = ctrl_name(pkt->hdr.code); linfo("Received control packet code %d (%s) from %s", pkt->hdr.code, ctrl, node ? node->name : "local Merlin daemon"); /* protect against bogus headers */ if (!node && (pkt->hdr.code == CTRL_INACTIVE || pkt->hdr.code == CTRL_ACTIVE)) { lerr("Received %s with unknown node id %d", ctrl, pkt->hdr.selection); return; } switch (pkt->hdr.code) { case CTRL_INACTIVE: /* * must memset() node->info before the disconnect handler * so we discard it in the peer id calculation dance if * we get data from it before it sends us a CTRL_ACTIVE * packet */ memset(&node->info, 0, sizeof(node->info)); node_set_state(node, STATE_NONE, "Received CTRL_INACTIVE"); break; case CTRL_ACTIVE: /* * Only mark the node as connected if the CTRL_ACTIVE packet * checks out properly and the info is new. If it *is* new, * we must re-do the peer assignment thing. */ if (!handle_ctrl_active(node, pkt)) { node_set_state(node, STATE_CONNECTED, "Received CTRL_ACTIVE"); assign_peer_ids(); } break; case CTRL_STALL: ctrl_stall_start(); break; case CTRL_RESUME: ctrl_stall_stop(); assign_peer_ids(); break; case CTRL_STOP: linfo("Received (and ignoring) CTRL_STOP event. What voodoo is this?"); break; default: lwarn("Unknown control code: %d", pkt->hdr.code); } }
etype etype::operator+(const etype &var) { switch(type){ case ET_INT: return(etype( *(int*)value + var.i() )); case ET_FLOAT: return(etype( *(float*)value + var.f() )); case ET_DOUBLE: return(etype( *(double*)value + var.d() )); case ET_CHAR: return(etype( *(char*)value + var.c() )); case ET_ESTR: return(etype( *(estr*)value + var.s() )); case ET_EARRAY: return(etype( *(estrarray*)value + var )); } lwarn("undefined value"); return(estr()); }
double etype::d() const { switch(type){ case ET_INT: return((double)*(int*)value); case ET_FLOAT: return((double)*(float*)value); case ET_DOUBLE: return(*(double*)value); case ET_CHAR: return((double)*(char*)value); case ET_ESTR: return((*(estr*)value).d()); case ET_EARRAY: return( (*(estrarray*)value)[0].d() ); } lwarn("undefined value"); return(0.0); }
bool etype::cmp_value(void *_value) const { switch(type){ case ET_INT: return(COMPARE(value,_value,int)); case ET_FLOAT: return(COMPARE(value,_value,float)); case ET_DOUBLE: return(COMPARE(value,_value,double)); case ET_CHAR: return(COMPARE(value,_value,char)); case ET_ESTR: return(COMPARE(value,_value,estr)); // case ET_EARRAY: return(COMPARE(value,_value,estrarray)); default: lwarn("undefined value"); } return(false); }
estrarray etype::a() const { switch(type){ case ET_INT: case ET_FLOAT: case ET_DOUBLE: case ET_CHAR: case ET_ESTR: return(estrarray(*this)); case ET_EARRAY: return(*(estrarray*)value); } lwarn("undefined value"); return(estrarray()); }
void grok_db_compound(struct cfg_comp *c) { unsigned int vi; use_database = 1; for (vi = 0; vi < c->vars; vi++) { struct cfg_var *v = c->vlist[vi]; if (!strcmp(v->key, "log_report_data")) { db_log_reports = strtobool(v->value); } else if (!prefixcmp(v->key, "log_notification")) { db_log_notifications = strtobool(v->value); } else if (!prefixcmp(v->key, "track_current")) { lwarn("Option '%s' in the database compound is deprecated", v->key); } else if (!strcmp(v->key, "enabled")) { use_database = strtobool(v->value); } else { sql_config(v->key, v->value); } } }
neb_cb_result * merlin_mod_hook(int cb, void *data) { merlin_event pkt; int result = 0; neb_cb_result *neb_result = NULL; static time_t last_pulse = 0, last_flood_warning = 0; time_t now; if (!data) { lerr("eventbroker module called with NULL data"); return neb_cb_result_create(-1); } else if (cb < 0 || cb > NEBCALLBACK_NUMITEMS) { lerr("merlin_mod_hook() called with invalid callback id"); return neb_cb_result_create(-1); } /* * must reset this here so events we don't check for * dupes are always sent properly */ check_dupes = 0; /* self-heal nodes that have missed out on the fact that we're up */ now = time(NULL); if(!last_pulse || now - last_pulse > 15) node_send_ctrl_active(&ipc, CTRL_GENERIC, &ipc.info); last_pulse = now; memset(&pkt, 0, sizeof(pkt)); pkt.hdr.type = cb; pkt.hdr.selection = DEST_BROADCAST; switch (cb) { case NEBCALLBACK_NOTIFICATION_DATA: neb_result = hook_notification(&pkt, data); break; case NEBCALLBACK_CONTACT_NOTIFICATION_METHOD_DATA: result = hook_contact_notification_method(&pkt, data); break; case NEBCALLBACK_HOST_CHECK_DATA: result = hook_host_result(&pkt, data); break; case NEBCALLBACK_SERVICE_CHECK_DATA: result = hook_service_result(&pkt, data); break; case NEBCALLBACK_COMMENT_DATA: result = hook_comment(&pkt, data); break; case NEBCALLBACK_DOWNTIME_DATA: result = hook_downtime(&pkt, data); break; case NEBCALLBACK_EXTERNAL_COMMAND_DATA: result = hook_external_command(&pkt, data); break; case NEBCALLBACK_FLAPPING_DATA: /* * flapping doesn't go to the network. check processing * will generate flapping alerts on all nodes anyway, */ case NEBCALLBACK_PROGRAM_STATUS_DATA: case NEBCALLBACK_PROCESS_DATA: /* these make no sense to ship across the wire */ pkt.hdr.code = MAGIC_NONET; result = send_generic(&pkt, data); break; case NEBCALLBACK_HOST_STATUS_DATA: case NEBCALLBACK_SERVICE_STATUS_DATA: /* * Don't handle status updates coming from Naemon. * If we need to send status updates for any reason it is done through * Merlin directly. For normal state updates, we let each node handle * check results so they keep their own state. */ break; case NEBCALLBACK_EVENT_HANDLER_DATA: result = hook_event_handler(&pkt, data); break; default: lerr("Unhandled callback '%s' in merlin_hook()", callback_name(cb)); } if (neb_result != NULL) { /* * We have a rich callback result, propagate return code * to preserve flood warnings */ result = neb_cb_result_returncode(neb_result); } else { /* * No rich callback result, create one */ neb_result = neb_cb_result_create_full(result, "No callback result description available"); } if (result < 0 && now - last_flood_warning > 30) { /* log a warning every 30 seconds */ last_flood_warning = now; lwarn("Daemon is flooded and backlogging failed"); } return neb_result; }
/* * if the import isn't done yet waitpid() will return 0 * and we won't touch importer_pid at all. */ static void reap_child_process(void) { int status, pid, i; if (!num_children) return; pid = waitpid(-1, &status, WNOHANG); if (pid < 0) { if (errno == ECHILD) { /* no child running. Just reset */ num_children = importer_pid = 0; } else { /* some random error. log it */ lerr("waitpid(-1...) failed: %s", strerror(errno)); } return; } /* child may not be done yet */ if (!pid) return; /* we reaped an actual child, so decrement the counter */ num_children--; /* looks like we reaped some helper we spawned */ linfo("Child with pid %d successfully reaped", pid); if (pid == importer_pid) { if (WIFEXITED(status)) { if (!WEXITSTATUS(status)) { linfo("import program finished. Resuming normal operations"); } else { lwarn("import program exited with return code %d", WEXITSTATUS(status)); } } else { lerr("import program stopped or killed. That's a Bad Thing(tm)"); } /* successfully reaped, so reset and resume */ importer_pid = 0; ipc_send_ctrl(CTRL_RESUME, CTRL_GENERIC); return; } /* not the importer program, so it must be an oconf push or fetch */ if (pid == csync.push.pid) { linfo("CSYNC: global push finished. Resuming"); csync.push.pid = 0; return; } else if (pid == csync.fetch.pid) { linfo("CSYNC: global fetch finished. Resuming"); csync.fetch.pid = 0; return; } for (i = 0; i < num_nodes; i++) { merlin_node *node = node_table[i]; if (!node->csync) continue; if (pid == node->csync->push.pid) { linfo("CSYNC: push finished for %s", node->name); node->csync->push.pid = 0; return; } else if (pid == node->csync->fetch.pid) { linfo("CSYNC: fetch finished from %s", node->name); node->csync->fetch.pid = 0; return; } } }
/* * Initiate a connection attempt to a node and mark it as PENDING. * Note that since we're using sockets in non-blocking mode (in order * to be able to effectively multiplex), the connection attempt will * never be completed in this function */ int net_try_connect(merlin_node *node) { int sockopt = 1; struct sockaddr *sa = (struct sockaddr *)&node->sain; int should_log = 0; struct timeval connect_timeout = { MERLIN_CONNECT_TIMEOUT, 0 }; struct sockaddr_in sain; time_t interval = MERLIN_CONNECT_INTERVAL; int result; /* don't log obsessively */ if (node->last_conn_attempt_logged + 30 <= time(NULL)) { should_log = 1; node->last_conn_attempt_logged = time(NULL); } if (!(node->flags & MERLIN_NODE_CONNECT)) { if (should_log) { linfo("CONN: Connect attempt blocked by config to %s node %s", node_type(node), node->name); } return 0; } /* don't bother trying to connect if it's pending or done */ switch (node->state) { case STATE_NEGOTIATING: if (node->conn_sock < 0) break; case STATE_CONNECTED: case STATE_PENDING: ldebug("CONN: node %s state is %s, so bailing", node->name, node_state_name(node->state)); return 0; } /* if it's not yet time to connect, don't even try it */ if (node->last_conn_attempt + interval > time(NULL)) { return 0; } /* mark the time so we can time it out ourselves if need be */ node->last_conn_attempt = time(NULL); /* create the socket if necessary */ if (node->conn_sock < 0) { node_disconnect(node, "struct reset (no real disconnect)"); node->conn_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (node->conn_sock < 0) { lerr("CONN: Failed to obtain connection socket for node %s: %s", node->name, strerror(errno)); lerr("CONN: Aborting connection attempt to %s", node->name); return -1; } } sa->sa_family = AF_INET; if (should_log) { linfo("CONN: Connecting to %s %s@%s:%d", node_type(node), node->name, inet_ntoa(node->sain.sin_addr), ntohs(node->sain.sin_port)); } if (setsockopt(node->conn_sock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(int))) { ldebug("CONN: Failed to set sockopt SO_REUSEADDR for node %s connect socket %d: %s", node->name, node->conn_sock, strerror(errno)); } if (node->flags & MERLIN_NODE_FIXED_SRCPORT) { ldebug("CONN: Using fixed source port %d for %s node %s", net_source_port(node), node_type(node), node->name); /* * first we bind() to a local port calculated by our own * listening port + the target port. */ sain.sin_family = AF_INET; sain.sin_port = htons(net_source_port(node)); sain.sin_addr.s_addr = 0; if (bind(node->conn_sock, (struct sockaddr *)&sain, sizeof(sain))) { lerr("CONN: Failed to bind() outgoing socket %d for node %s to port %d: %s", node->conn_sock, node->name, ntohs(sain.sin_port), strerror(errno)); if (errno == EBADF || errno == EADDRINUSE) { close(node->conn_sock); node->conn_sock = -1; return -1; } } } if (fcntl(node->conn_sock, F_SETFL, O_NONBLOCK) < 0) { lwarn("CONN: Failed to set socket %d for %s non-blocking: %s", node->conn_sock, node->name, strerror(errno)); } if (setsockopt(node->conn_sock, SOL_SOCKET, SO_RCVTIMEO, &connect_timeout, sizeof(connect_timeout)) < 0) { ldebug("CONN: Failed to set receive timeout for %d, node %s: %s", node->conn_sock, node->name, strerror(errno)); } if (setsockopt(node->conn_sock, SOL_SOCKET, SO_SNDTIMEO, &connect_timeout, sizeof(connect_timeout)) < 0) { ldebug("CONN: Failed to set send timeout for %d, node %s: %s", node->conn_sock, node->name, strerror(errno)); } if (connect(node->conn_sock, sa, sizeof(struct sockaddr_in)) < 0) { if (errno == EINPROGRESS) { /* * non-blocking socket and connect() can't be completed * immediately (ie, the normal case) */ node_set_state(node, STATE_PENDING, "Connecting"); } else if (errno == EALREADY) { ldebug("CONN: Connect already in progress for socket %d to %s. This should never happen", node->conn_sock, node->name); node_set_state(node, STATE_PENDING, "connect() already in progress"); } else { /* a real connection error */ ldebug("CONN: connect() via %d to %s failed: %s", node->conn_sock, node->name, strerror(errno)); close(node->conn_sock); node->conn_sock = -1; if (should_log) { node_disconnect(node, "CONN: connect() failed to %s node '%s' (%s:%d): %s", node_type(node), node->name, inet_ntoa(node->sain.sin_addr), ntohs(node->sain.sin_port), strerror(errno)); } else { node_disconnect(node, NULL); } return -1; } } result = iobroker_register_out(nagios_iobs, node->conn_sock, node, conn_writable); if (result < 0) { node_disconnect(node, "IOB: Failed to register %s connect socket %d with iobroker: %s", node->name, node->conn_sock, iobroker_strerror(result)); close(node->conn_sock); node->conn_sock = -1; return -1; } return 0; }
static void cs_write (void *opaque, target_phys_addr_t addr, uint64_t val64, unsigned size) { CSState *s = opaque; uint32_t saddr, iaddr, val; saddr = addr; val = val64; switch (saddr) { case Index_Address: if (!(s->regs[Index_Address] & MCE) && (val & MCE) && (s->dregs[Interface_Configuration] & (3 << 3))) s->aci_counter = conf.aci_counter; s->regs[Index_Address] = val & ~(1 << 7); break; case Index_Data: if (!(s->dregs[MODE_And_ID] & MODE2)) iaddr = s->regs[Index_Address] & 0x0f; else iaddr = s->regs[Index_Address] & 0x1f; switch (iaddr) { case RESERVED: case RESERVED_2: case RESERVED_3: lwarn ("attempt to write %#x to reserved indirect register %d\n", val, iaddr); break; case FS_And_Playback_Data_Format: if (s->regs[Index_Address] & MCE) { cs_reset_voices (s, val); } else { if (s->dregs[Alternate_Feature_Status] & PMCE) { val = (val & ~0x0f) | (s->dregs[iaddr] & 0x0f); cs_reset_voices (s, val); } else { lwarn ("[P]MCE(%#x, %#x) is not set, val=%#x\n", s->regs[Index_Address], s->dregs[Alternate_Feature_Status], val); break; } } s->dregs[iaddr] = val; break; case Interface_Configuration: val &= ~(1 << 5); /* D5 is reserved */ s->dregs[iaddr] = val; if (val & PPIO) { lwarn ("PIO is not supported (%#x)\n", val); break; } if (val & PEN) { if (!s->dma_running) { cs_reset_voices (s, s->dregs[FS_And_Playback_Data_Format]); } } else { if (s->dma_running) { DMA_release_DREQ (s->dma); AUD_set_active_out (s->voice, 0); s->dma_running = 0; } } break; case Error_Status_And_Initialization: lwarn ("attempt to write to read only register %d\n", iaddr); break; case MODE_And_ID: dolog ("val=%#x\n", val); if (val & MODE2) s->dregs[iaddr] |= MODE2; else s->dregs[iaddr] &= ~MODE2; break; case Alternate_Feature_Enable_I: if (val & TE) lerr ("timer is not yet supported\n"); s->dregs[iaddr] = val; break; case Alternate_Feature_Status: if ((s->dregs[iaddr] & PI) && !(val & PI)) { /* XXX: TI CI */ qemu_irq_lower (s->pic); s->regs[Status] &= ~INT; } s->dregs[iaddr] = val; break; case Version_Chip_ID: lwarn ("write to Version_Chip_ID register %#x\n", val); s->dregs[iaddr] = val; break; default: s->dregs[iaddr] = val; break; } dolog ("written value %#x to indirect register %d\n", val, iaddr); break; case Status: if (s->regs[Status] & INT) { qemu_irq_lower (s->pic); } s->regs[Status] &= ~INT; s->dregs[Alternate_Feature_Status] &= ~(PI | CI | TI); break; case PIO_Data: lwarn ("attempt to write value %#x to PIO register\n", val); break; } }
int main(int argc, char **argv) { int ch = 0; int cmd = UD_MIN; int sock = -1; char *file = NULL; char * const short_options = "uds:t:"; struct option log_options[] = { { "upload", 0, NULL, 'u' }, { "download", 0, NULL, 'd' }, { "file", 1, NULL, 's' }, }; if (argc < 2) { help(); return -1; } while ((ch = getopt_long(argc, argv, short_options, log_options, NULL)) != EOF) { switch (ch) { case 'u': cmd = UD_UPLOAD; break; case 'd': cmd = UD_DOWNLOAD; break; case 's': file = optarg; break; break; default: lwarn("unknown argument, %s", argv[optind]); break; } } if (-1 == check_param(cmd, file)) { lerror("check param failed"); help(); goto ERR; } linfo("cmd: %s, file: %s", string_cmd(cmd), file); sock = create_client_socket(); if (-1 == sock) { lerror("call create_and_connect_socket() failed"); goto ERR; } ldebug("create socket success, sock: %d", sock); switch (cmd) { case UD_UPLOAD: (void)client_upload(sock, file); break; case UD_DOWNLOAD: (void)client_download(sock, file); break; default: break; } return 0; ERR: if (sock >= 0) { close(sock); } return -1; }
void check_options (void) { int i; const char * m4 = NULL; if (lex_compat) { if (C_plus_plus) flexerror (_("Can't use -+ with -l option")); if (fulltbl || fullspd) flexerror (_("Can't use -f or -F with -l option")); if (reentrant || bison_bridge_lval) flexerror (_ ("Can't use --reentrant or --bison-bridge with -l option")); yytext_is_array = true; do_yylineno = true; use_read = false; } #if 0 /* This makes no sense whatsoever. I'm removing it. */ if (do_yylineno) /* This should really be "maintain_backup_tables = true" */ reject_really_used = true; #endif if (csize == unspecified) { if ((fulltbl || fullspd) && !useecs) csize = DEFAULT_CSIZE; else csize = CSIZE; } if (interactive == unspecified) { if (fulltbl || fullspd) interactive = false; else interactive = true; } if (fulltbl || fullspd) { if (usemecs) flexerror (_ ("-Cf/-CF and -Cm don't make sense together")); if (interactive) flexerror (_("-Cf/-CF and -I are incompatible")); if (lex_compat) flexerror (_ ("-Cf/-CF are incompatible with lex-compatibility mode")); if (fulltbl && fullspd) flexerror (_ ("-Cf and -CF are mutually exclusive")); } if (C_plus_plus && fullspd) flexerror (_("Can't use -+ with -CF option")); if (C_plus_plus && yytext_is_array) { lwarn (_("%array incompatible with -+ option")); yytext_is_array = false; } if (C_plus_plus && (reentrant)) flexerror (_("Options -+ and --reentrant are mutually exclusive.")); if (C_plus_plus && bison_bridge_lval) flexerror (_("bison bridge not supported for the C++ scanner.")); if (useecs) { /* Set up doubly-linked equivalence classes. */ /* We loop all the way up to csize, since ecgroup[csize] is * the position used for NUL characters. */ ecgroup[1] = NIL; for (i = 2; i <= csize; ++i) { ecgroup[i] = i - 1; nextecm[i - 1] = i; } nextecm[csize] = NIL; } else { /* Put everything in its own equivalence class. */ for (i = 1; i <= csize; ++i) { ecgroup[i] = i; nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */ } } if (extra_type) buf_m4_define( &m4defs_buf, "M4_EXTRA_TYPE_DEFS", extra_type); if (!use_stdout) { FILE *prev_stdout; if (!did_outfilename) { char *suffix; if (C_plus_plus) suffix = "cc"; else suffix = "c"; snprintf (outfile_path, sizeof(outfile_path), outfile_template, prefix, suffix); outfilename = outfile_path; } prev_stdout = freopen (outfilename, "w+", stdout); if (prev_stdout == NULL) lerr (_("could not create %s"), outfilename); outfile_created = 1; } /* Setup the filter chain. */ output_chain = filter_create_int(NULL, filter_tee_header, headerfilename); if ( !(m4 = getenv("M4"))) { char *slash; m4 = M4; if ((slash = strrchr(M4, '/')) != NULL) { m4 = slash+1; /* break up $PATH */ const char *path = getenv("PATH"); if (!path) { m4 = M4; } else { int m4_length = strlen(m4); do { size_t length = strlen(path); struct stat sbuf; const char *endOfDir = strchr(path, ':'); if (!endOfDir) endOfDir = path+length; { char *m4_path = calloc(endOfDir-path + 1 + m4_length + 1, 1); memcpy(m4_path, path, endOfDir-path); m4_path[endOfDir-path] = '/'; memcpy(m4_path + (endOfDir-path) + 1, m4, m4_length + 1); if (stat(m4_path, &sbuf) == 0 && (S_ISREG(sbuf.st_mode)) && sbuf.st_mode & S_IXUSR) { m4 = m4_path; break; } free(m4_path); } path = endOfDir+1; } while (path[0]); if (!path[0]) m4 = M4; } } } filter_create_ext(output_chain, m4, "-P", 0); filter_create_int(output_chain, filter_fix_linedirs, NULL); /* For debugging, only run the requested number of filters. */ if (preproc_level > 0) { filter_truncate(output_chain, preproc_level); filter_apply_chain(output_chain); } yyout = stdout; /* always generate the tablesverify flag. */ buf_m4_define (&m4defs_buf, "M4_YY_TABLES_VERIFY", tablesverify ? "1" : "0"); if (tablesext) gentables = false; if (tablesverify) /* force generation of C tables. */ gentables = true; if (tablesext) { FILE *tablesout; struct yytbl_hdr hdr; char *pname = 0; size_t nbytes = 0; buf_m4_define (&m4defs_buf, "M4_YY_TABLES_EXTERNAL", NULL); if (!tablesfilename) { nbytes = strlen (prefix) + strlen (tablesfile_template) + 2; tablesfilename = pname = calloc(nbytes, 1); snprintf (pname, nbytes, tablesfile_template, prefix); } if ((tablesout = fopen (tablesfilename, "w")) == NULL) lerr (_("could not create %s"), tablesfilename); free(pname); tablesfilename = 0; yytbl_writer_init (&tableswr, tablesout); nbytes = strlen (prefix) + strlen ("tables") + 2; tablesname = calloc(nbytes, 1); snprintf (tablesname, nbytes, "%stables", prefix); yytbl_hdr_init (&hdr, flex_version, tablesname); if (yytbl_hdr_fwrite (&tableswr, &hdr) <= 0) flexerror (_("could not write tables header")); } if (skelname && (skelfile = fopen (skelname, "r")) == NULL) lerr (_("can't open skeleton file %s"), skelname); if (reentrant) { buf_m4_define (&m4defs_buf, "M4_YY_REENTRANT", NULL); if (yytext_is_array) buf_m4_define (&m4defs_buf, "M4_YY_TEXT_IS_ARRAY", NULL); } if ( bison_bridge_lval) buf_m4_define (&m4defs_buf, "M4_YY_BISON_LVAL", NULL); if ( bison_bridge_lloc) buf_m4_define (&m4defs_buf, "<M4_YY_BISON_LLOC>", NULL); if (strchr(prefix, '[') || strchr(prefix, ']')) flexerror(_("Prefix cannot include '[' or ']'")); buf_m4_define(&m4defs_buf, "M4_YY_PREFIX", prefix); if (did_outfilename) line_directive_out (stdout, 0); if (do_yylineno) buf_m4_define (&m4defs_buf, "M4_YY_USE_LINENO", NULL); /* Create the alignment type. */ buf_strdefine (&userdef_buf, "YY_INT_ALIGNED", long_align ? "long int" : "short int"); /* Define the start condition macros. */ { struct Buf tmpbuf; buf_init(&tmpbuf, sizeof(char)); for (i = 1; i <= lastsc; i++) { char *str, *fmt = "#define %s %d\n"; size_t strsz; strsz = strlen(fmt) + strlen(scname[i]) + (size_t)(1 + ceil (log10(i))) + 2; str = malloc(strsz); if (!str) flexfatal(_("allocation of macro definition failed")); snprintf(str, strsz, fmt, scname[i], i - 1); buf_strappend(&tmpbuf, str); free(str); } buf_m4_define(&m4defs_buf, "M4_YY_SC_DEFS", tmpbuf.elts); buf_destroy(&tmpbuf); } /* This is where we begin writing to the file. */ /* Dump the %top code. */ if( top_buf.elts) outn((char*) top_buf.elts); /* Dump the m4 definitions. */ buf_print_strings(&m4defs_buf, stdout); m4defs_buf.nelts = 0; /* memory leak here. */ /* Place a bogus line directive, it will be fixed in the filter. */ if (gen_line_dirs) outn("#line 0 \"M4_YY_OUTFILE_NAME\"\n"); /* Dump the user defined preproc directives. */ if (userdef_buf.elts) outn ((char *) (userdef_buf.elts)); skelout (); /* %% [1.0] */ }
void eseqclusterData::getCluster(const eintarray& seqs, eintarray& seqcluster,float& cdist) { if (seqs.size()<2) { lwarn("seqs is empty or contains only one sequence: "+estr(seqs.size())); return; } if (mergearr.size()==0 || count==0) { lwarn("empty merge array, load the cluster merge file"); return; } int i,j,k; earray<eintarray> otus; otus.init(count); eintarray otuarr; otuarr.init(count); for (i=0; i<otuarr.size(); ++i){ otuarr[i]=i; otus[i].add(i); } // cout << "# finding cluster for: " << seqs.size() << endl; // point at the seq we merged with float lastdist=mergearr[0].dist; bool allin=false; for (i=0; i<mergearr.size(); ++i){ if (lastdist != mergearr[i].dist){ allin=true; for (k=seqs[0]; k!=otuarr[k]; k=otuarr[k]); otuarr[seqs[0]]=k; for (j=1; j<seqs.size(); ++j){ for (k=seqs[j]; k!=otuarr[k]; k=otuarr[k]); otuarr[seqs[j]]=k; if (otuarr[seqs[0]] != otuarr[seqs[j]]) { allin=false; break; } } if (allin) break; lastdist=mergearr[i].dist; // cout << "# lastdist: " << lastdist << endl; } otuarr[mergearr[i].y]=mergearr[i].x; /* otus[mergearr[i].x]+=otus[mergearr[i].y]; for (j=0; j<otus[mergearr[i].y].size(); ++j) otuarr[otus[mergearr[i].y][j]]=mergearr[i].x; otus[mergearr[i].y].clear(); */ } // cout << "# finished" << endl; if (allin){ cdist=lastdist; for (k=seqs[0]; k!=otuarr[k]; k=otuarr[k]); otuarr[seqs[0]]=k; for (i=0; i<otuarr.size(); ++i){ for (k=i; k!=otuarr[k]; k=otuarr[k]); otuarr[i]=k; if (otuarr[i]==otuarr[seqs[0]]) seqcluster.add(i); } return; } for (j=0; j<seqs.size(); ++j){ for (k=seqs[j]; k!=otuarr[k]; k=otuarr[k]); otuarr[seqs[j]]=k; } // estr str; // for (j=0; j<seqs.size(); ++j) // str+=","+estr(otuarr[seqs[j]]); // cout << str.substr(1) << endl; cdist=-1.0; }
static int handle_ipc_event(merlin_event *pkt) { int result = 0; unsigned int i; if (pkt->hdr.type == CTRL_PACKET) { switch (pkt->hdr.code) { case CTRL_PATHS: read_nagios_paths(pkt); return 0; case CTRL_ACTIVE: /* * handle_ctrl_active() should basically never return * anything but 0 or 1 from our module. If it does, it * will already have logged everything the user needs * to know, so we can just return without further * actions, even if the info returned is the same as * we already have, but if no problems were found we * forward the packet to the network anyway. */ result = handle_ctrl_active(&ipc, pkt); if (result < 0) { /* ipc is incompatible with us. weird */ return 0; } /* * info checks out, so we forward it. If ipc resent same * info, we won't do the config sync check */ if (result >= 1) { break; } /* * info checks out and is new. Check to see if we * should run any config sync actions. */ for (i = 0; i < num_nodes; i++) { merlin_node *node = node_table[i]; /* skip nodes that have no start or mtime */ if (!node->info.start.tv_sec || !node->info.last_cfg_change) continue; csync_node_active(node_table[i]); } break; case CTRL_INACTIVE: /* this should really never happen, but forward it if it does */ memset(&ipc.info, 0, sizeof(ipc.info)); break; default: lwarn("forwarding control packet %d to the network", pkt->hdr.code); break; } } /* * we must send to the network before we run mrm_db_update(), * since the latter deblockifies the packet and makes it * unusable in network transfers without repacking, but only * if this isn't magically marked as a NONET event */ if (pkt->hdr.code != MAGIC_NONET) result = net_send_ipc_data(pkt); /* skip sending control packets to database */ if (use_database && pkt->hdr.type != CTRL_PACKET) result |= mrm_db_update(&ipc, pkt); return result; }
int main(int argc, char **argv) { int i, result; progname = strrchr(argv[0], '/'); progname = progname ? progname + 1 : argv[0]; is_module = 0; ipc_init_struct(); gettimeofday(&self.start, NULL); /* * Solaris doesn't support MSG_NOSIGNAL, so * we ignore SIGPIPE globally instead */ signal(SIGPIPE, SIG_IGN); for (i = 1; i < argc; i++) { char *opt, *arg = argv[i]; if (*arg != '-') { if (!merlin_conf) { merlin_conf = arg; continue; } goto unknown_argument; } if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) usage(NULL); if (!strcmp(arg, "-k") || !strcmp(arg, "--kill")) { killing = 1; continue; } if (!strcmp(arg, "-d") || !strcmp(arg, "--debug")) { debug++; continue; } if ((opt = strchr(arg, '='))) opt++; else if (i < argc - 1) opt = argv[i + 1]; else usage("Unknown argument, or argument '%s' requires a parameter", arg); i++; if (!strcmp(arg, "--config") || !strcmp(arg, "-c")) { merlin_conf = opt; continue; } unknown_argument: usage("Unknown argument: %s", arg); } if (!merlin_conf) usage("No config-file specified\n"); if (!grok_config(merlin_conf)) { fprintf(stderr, "%s contains errors. Bailing out\n", merlin_conf); return 1; } if (!pidfile) pidfile = "/var/run/merlin.pid"; if (killing) return kill_daemon(pidfile); if (use_database && !import_program) { lwarn("Using database, but no import program configured. Are you sure about this?"); lwarn("If not, make sure you specify the import_program directive in"); lwarn("the \"daemon\" section of your merlin configuration file"); } ipc.action = ipc_action_handler; result = ipc_init(); if (result < 0) { printf("Failed to initalize ipc socket: %s\n", strerror(errno)); return 1; } if (net_init() < 0) { printf("Failed to initialize networking: %s\n", strerror(errno)); return 1; } if (!debug) { if (daemonize(merlin_user, NULL, pidfile, 0) < 0) exit(EXIT_FAILURE); /* * we'll leak these file-descriptors, but that * doesn't really matter as we just want accidental * output to go somewhere where it'll be ignored */ fclose(stdin); open("/dev/null", O_RDONLY); fclose(stdout); open("/dev/null", O_WRONLY); fclose(stderr); open("/dev/null", O_WRONLY); } signal(SIGINT, clean_exit); signal(SIGTERM, clean_exit); signal(SIGUSR1, sigusr_handler); signal(SIGUSR2, sigusr_handler); sql_init(); if (use_database) { sql_query("TRUNCATE TABLE program_status"); sql_query("INSERT INTO program_status(instance_id, instance_name, is_running) " "VALUES(0, 'Local Nagios daemon', 0)"); for (i = 0; i < (int)num_nodes; i++) { char *node_name; merlin_node *node = noc_table[i]; sql_quote(node->name, &node_name); sql_query("INSERT INTO program_status(instance_id, instance_name, is_running) " "VALUES(%d, %s, 0)", node->id + 1, node_name); safe_free(node_name); } } state_init(); linfo("Merlin daemon %s successfully initialized", merlin_version); polling_loop(); clean_exit(0); return 0; }
/* * Initiate a connection attempt to a node and mark it as PENDING. * Note that since we're using sockets in non-blocking mode (in order * to be able to effectively multiplex), the connection attempt will * never be completed in this function */ int net_try_connect(merlin_node *node) { int sockopt = 1; struct sockaddr *sa = (struct sockaddr *)&node->sain; int connected = 0, should_log = 0; struct timeval connect_timeout = { MERLIN_CONNECT_TIMEOUT, 0 }; struct sockaddr_in sain; time_t interval = MERLIN_CONNECT_INTERVAL; /* don't log obsessively */ if (node->last_conn_attempt_logged + 30 <= time(NULL)) { should_log = 1; node->last_conn_attempt_logged = time(NULL); } if (!(node->flags & MERLIN_NODE_CONNECT)) { if (should_log) { linfo("Connect attempt blocked by config to %s node %s", node_type(node), node->name); } return 0; } /* if it's not yet time to connect, don't even try it */ if (node->last_conn_attempt + interval > time(NULL)) { ldebug("connect to %s blocked for %lu more seconds", node->name, node->last_conn_attempt + interval - time(NULL)); return 0; } /* mark the time so we can time it out ourselves if need be */ node->last_conn_attempt = time(NULL); /* create the socket if necessary */ if (node->sock < 0) { node_disconnect(node, "struct reset (no real disconnect)"); node->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (node->sock < 0) { lerr("Failed to obtain socket for node %s: %s", node->name, strerror(errno)); lerr("Aborting connection attempt to %s", node->name); return -1; } } /* * don't try to connect to a node if an attempt is already pending, * but do check if the connection has completed successfully */ if (node->state == STATE_PENDING || node->state == STATE_CONNECTED) { if (net_is_connected(node)) node_set_state(node, STATE_CONNECTED, "Attempted connect completed"); return 0; } sa->sa_family = AF_INET; if (should_log) { linfo("Connecting to %s %s@%s:%d", node_type(node), node->name, inet_ntoa(node->sain.sin_addr), ntohs(node->sain.sin_port)); } (void)setsockopt(node->sock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(int)); if (node->flags & MERLIN_NODE_FIXED_SRCPORT) { ldebug("Using fixed source port for %s node %s", node_type(node), node->name); /* * first we bind() to a local port calculated by our own * listening port + the target port. */ sain.sin_family = AF_INET; sain.sin_port = htons(net_source_port(node)); sain.sin_addr.s_addr = 0; if (bind(node->sock, (struct sockaddr *)&sain, sizeof(sain))) { lerr("Failed to bind() outgoing socket for node %s to port %d: %s", node->name, ntohs(sain.sin_port), strerror(errno)); } } if (fcntl(node->sock, F_SETFL, O_NONBLOCK) < 0) { lwarn("Failed to set socket for %s non-blocking: %s", node->name, strerror(errno)); } if (setsockopt(node->sock, SOL_SOCKET, SO_RCVTIMEO, &connect_timeout, sizeof(connect_timeout)) < 0) { ldebug("Failed to set receive timeout for node %s: %s", node->name, strerror(errno)); } if (setsockopt(node->sock, SOL_SOCKET, SO_SNDTIMEO, &connect_timeout, sizeof(connect_timeout)) < 0) { ldebug("Failed to set send timeout for node %s: %s", node->name, strerror(errno)); } if (connect(node->sock, sa, sizeof(struct sockaddr_in)) < 0) { if (errno == EINPROGRESS || errno == EALREADY) { node_set_state(node, STATE_PENDING, "connect() already in progress"); } else if (errno == EISCONN) { connected = 1; } else { if (should_log) { node_disconnect(node, "connect() failed to %s node '%s' (%s:%d): %s", node_type(node), node->name, inet_ntoa(node->sain.sin_addr), ntohs(node->sain.sin_port), strerror(errno)); } else { node_disconnect(node, NULL); } return -1; } } if (connected || net_is_connected(node)) { linfo("Successfully connected to %s %s@%s:%d", node_type(node), node->name, inet_ntoa(node->sain.sin_addr), ntohs(node->sain.sin_port)); node_set_state(node, STATE_CONNECTED, "connect() successful"); } else { if (should_log) { linfo("Connection pending to %s %s@%s:%d", node_type(node), node->name, inet_ntoa(node->sain.sin_addr), ntohs(node->sain.sin_port)); } node_set_state(node, STATE_PENDING, "connect() in progress"); } return 0; }