bool PaceFilter::setup() { if (findFilter("queue", true) == nullptr && std::dynamic_pointer_cast<LinkConnect>(conn.lock()) != nullptr) ERRORPRINTF(t, E_NOTICE, "The 'pace' filter without a queue acts globally."); if (!Filter::setup()) return false; delay = cfg->value("delay",15)/1000.; if (delay <= 0) { ERRORPRINTF(t, E_ERROR, "The delay must be >0"); return false; } byte_delay = cfg->value("delay-per-byte",1)/1000.; if (byte_delay < 0) { ERRORPRINTF(t, E_ERROR, "The delay must be >0"); return false; } factor_in = cfg->value("incoming",0.75); if (factor_in < 0) { ERRORPRINTF(t, E_ERROR, "The factor for incoming packets must be >=0"); return false; } return true; }
void insert_parent_fd(fd_item_t * fd_item, int fd) { int i; int index = -1; int * parents = fd_item->fd_map->parent_fds; for(i = 0; i < MAX_PARENT_IDS; i++) { if (parents[i] == fd) { ERRORPRINTF("Fd %d is already present in parent fds array...\n", fd); assert(1 == 0); return; } if (parents[i] == -1) { index = i; break; } } if (index != -1) { parents[index] = fd; fd_item->fd_map->last_par_index++; } else { ERRORPRINTF("Array of parrent fds is full! My_fd is: :%d\n", fd_item->fd_map->my_fd); } }
int delete_parent_fd(fd_item_t * fd_item, int fd) { int i; int * parents = fd_item->fd_map->parent_fds; for(i = 0; i < MAX_PARENT_IDS; i++) { if (parents[i] == fd) { int idx = fd_item->fd_map->last_par_index; if ( i == fd_item->fd_map->last_par_index ) { //last item in the list parents[i] = -1; } else if ( idx > 0 ) { parents[i] = parents[idx]; parents[idx] = -1; } else { ERRORPRINTF("Sanity check error: last_par_index out of bounds: %d\n", idx); assert(1 == 0); } fd_item->fd_map->last_par_index--; break; } if (parents[i] == -1) { ERRORPRINTF("Didn't find fd %d in parent fds\n", fd); assert(1 == 0); break; } } return fd_item->fd_map->last_par_index == -1; }
gboolean ipc_sys_is_in_portrait_mode(void) { gboolean result = TRUE; eripc_error_t retval; eripc_event_info_t* info = NULL; LOGPRINTF("entry"); retval = eripc_send_varargs_and_wait(eripcClient->context, &info, ERIPC_BUS_SESSION, DBUS_SERVICE_SYSTEM_CONTROL, "sysGetOrientation", ERIPC_TYPE_INVALID); if (retval != ERIPC_ERROR_SUCCESS) { ERRORPRINTF("Error launching eripc handler"); } else if (info == NULL || info->args == NULL) { ERRORPRINTF("sysd returns OK but no reply structure"); } else { const eripc_arg_t *arg_array = info->args; if (arg_array[0].type == ERIPC_TYPE_STRING) { if ( strcmp("portrait", arg_array[0].value.s) == 0 ) { result = TRUE; } else { result = FALSE; } } else { result = FALSE ; } } eripc_event_info_free(eripcClient->context, info); return result; }
bool EIBNetIPTunnel::setup() { // Force queuing so that a broken or unreachable server can't disable the whole system if (!assureFilter("queue", true)) return false; if (!BusDriver::setup()) return false; dest = cfg->value("ip-address",""); if (!dest.size()) { ERRORPRINTF (t, E_ERROR | 23, "The 'ipt' driver, section %s, requires an 'ip-address=' option", cfg->name); return false; } port = cfg->value("dest-port",3671); sport = cfg->value("src-port",0); NAT = cfg->value("nat",false); monitor = cfg->value("monitor",false); if(NAT) { srcip = cfg->value("nat-ip",""); dataport = cfg->value("data-port",0); } heartbeat_time = cfg->value("heartbeat-timer",30); heartbeat_limit = cfg->value("heartbeat-retries",3); return true; }
void delete_process_ht(hash_table_t * fd_mappings, int32_t pid) { item_t * process_ht_item; if ( (process_ht_item = hash_table_find(fd_mappings, &pid)) != NULL ) { hash_table_remove(fd_mappings, &pid); } else { ERRORPRINTF("Can not find pid %"PRIi32" when removing delete_process_ht\n", pid); } }
bool QueueFilter::setup() { if(std::dynamic_pointer_cast<LinkConnect>(conn.lock()) == nullptr) { ERRORPRINTF(t, E_ERROR, "You can't use the 'queue' filter globally"); return false; } if (findFilter("queue", true) != nullptr) { ERRORPRINTF(t, E_WARNING, "Two queue filters on a link does not make sense"); return false; } if (!Filter::setup()) return false; // XXX options? return true; }
void QueueFilter::send_Next() { switch(state) { case Q_DOWN: ERRORPRINTF(t, E_WARNING, "send_Next while down"); break; case Q_IDLE: ERRORPRINTF(t, E_WARNING, "spurious send_Next"); break; case Q_BUSY: trigger.send(); // fall thru case Q_SENDING: state = Q_IDLE; break; } }
bool TPUARTwrap::setup() { ackallgroup = cfg->value("ack-group",false); ackallindividual = cfg->value("ack-individual",false); monitor = cfg->value("monitor",false); if (cfg->value("device","").length() > 0) { if (cfg->value("ip-address","").length() > 0 || cfg->value("port",-1) != -1) { ERRORPRINTF (t, E_ERROR, "Don't specify both device and IP options!"); return false; } iface = create_serial(this, cfg); } else { if (cfg->value("baudrate",-1) != -1) { ERRORPRINTF (t, E_ERROR, "Don't specify both device and IP options!"); return false; } iface = new LLtcp(this, cfg); } if (t->ShowPrint(0)) iface = new LLlog (this,cfg, iface); FilterPtr single = findFilter("single"); if (single != nullptr) { std::shared_ptr<NatL2Filter> f = std::dynamic_pointer_cast<NatL2Filter>(single); if (f) my_addr = f->addr; } if (!LowLevelFilter::setup()) return false; return true; }
gboolean ipc_sys_is_pageturn_inverted() { gboolean result = FALSE; eripc_error_t retval; eripc_event_info_t* info = NULL; LOGPRINTF("entry"); retval = eripc_send_varargs_and_wait(eripcClient->context, &info, ERIPC_BUS_SESSION, DBUS_SERVICE_SYSTEM_CONTROL, "sysGetPageturnInverted", ERIPC_TYPE_INVALID); if (retval != ERIPC_ERROR_SUCCESS) { ERRORPRINTF("Error launching eripc handler"); } else if (info == NULL || info->args == NULL) { ERRORPRINTF("sysd returns OK but no reply structure"); } else { const eripc_arg_t *arg_array = info->args; if (arg_array[0].type == ERIPC_TYPE_BOOL) { result = (gboolean) arg_array[0].value.b; } else { result = FALSE ; } } eripc_event_info_free(eripcClient->context, info); return result; }
bool LLtcp::setup() { if(!FDdriver::setup()) return false; dest = cfg->value("ip-address",""); port = cfg->value("dest-port",0); if (dest.size() == 0) { ERRORPRINTF (t, E_ERROR | 52, "%s: 'ip-address=<host>' required", cfg->name); return false; } if (port == 0) { ERRORPRINTF (t, E_ERROR | 52, "%s: 'port=<num>' required", cfg->name); return false; } return true; }
void LLtcp::start() { int reuse = 1; int nodelay = 1; struct sockaddr_in addr; if (!GetHostIP (t, &addr, dest.c_str())) { ERRORPRINTF (t, E_ERROR | 52, "Lookup of %s failed: %s", dest, strerror(errno)); goto ex1; } addr.sin_port = htons (port); fd = socket (AF_INET, SOCK_STREAM, 0); if (fd == -1) { ERRORPRINTF (t, E_ERROR | 52, "Opening %s:%d failed: %s", dest,port, strerror(errno)); goto ex1; } if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) == -1) { ERRORPRINTF (t, E_ERROR | 53, "Connect %s:%d: connect: %s", dest,port, strerror(errno)); goto ex2; } setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof (reuse)); setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof (nodelay)); TRACEPRINTF (t, 2, "Opened"); FDdriver::start(); return; ex2: close (fd); fd = -1; ex1: stopped(); }
void QueueFilter::started() { switch(state) { case Q_DOWN: state = Q_IDLE; break; default: ERRORPRINTF(t, E_WARNING, "state %d??", state); break; } Filter::started(); }
void PaceFilter::started() { switch(state) { case P_DOWN: if (want_next) Filter::send_Next(); state = P_IDLE; break; default: ERRORPRINTF(t, E_WARNING, "state %d??", state); break; } Filter::started(); }
SystemdServer::SystemdServer (Layer3 * la3, Trace * tr, int systemd_fd): Server (la3, tr) { TRACEPRINTF (tr, 8, this, "OpenSystemdSocket"); fd = systemd_fd; if (listen (fd, 10) == -1) { ERRORPRINTF (tr, E_ERROR | 18, this, "OpenSystemdSocket: listen: %s", strerror(errno)); close (fd); fd = -1; return; } TRACEPRINTF (tr, 8, this, "SystemdSocket opened"); Start (); }
void EIBNetIPRouter::start() { struct sockaddr_in baddr; struct ip_mreq mcfg; TRACEPRINTF (t, 2, "Open"); memset (&baddr, 0, sizeof (baddr)); #ifdef HAVE_SOCKADDR_IN_LEN baddr.sin_len = sizeof (baddr); #endif baddr.sin_family = AF_INET; baddr.sin_port = htons (port); baddr.sin_addr.s_addr = htonl (INADDR_ANY); sock = new EIBNetIPSocket (baddr, 1, t); if (!sock->init ()) goto err_out; sock->on_recv.set<EIBNetIPRouter,&EIBNetIPRouter::read_cb>(this); if (! sock->SetInterface(interface)) { ERRORPRINTF (t, E_ERROR | 58, "interface %s not recognized", interface); goto err_out; } sock->recvall = 2; if (GetHostIP (t, &sock->sendaddr, multicastaddr) == 0) goto err_out; sock->sendaddr.sin_port = htons (port); if (!GetSourceAddress (t, &sock->sendaddr, &sock->localaddr)) goto err_out; sock->localaddr.sin_port = sock->sendaddr.sin_port; mcfg.imr_multiaddr = sock->sendaddr.sin_addr; mcfg.imr_interface.s_addr = htonl (INADDR_ANY); if (!sock->SetMulticast (mcfg)) goto err_out; TRACEPRINTF (t, 2, "Opened"); BusDriver::start(); return; err_out: delete sock; sock = 0; stopped(); }
void PluginViewImpl::handle_page_ready(RenderResultPtr result, RenderStatus stat) { if (result == 0) { // the render result cannot be NULL return; } PluginEventAttrs attrs; // set reference id attrs.render_end.rid = result->get_ref_id(); // set render result attrs.render_end.result = static_cast<IPluginUnknown *>(result); switch (stat) { case TASK_RENDER_DONE: { // render done attrs.render_end.status = RENDER_DONE; } break; case TASK_RENDER_OOM: { // out of memory attrs.render_end.status = RENDER_OUT_OF_MEMORY; WARNPRINTF("Tell UDS out of memory, task %ld is aborted", attrs.render_end.rid); } break; case TASK_RENDER_INVALID_PAGE: { // it is an invalid page attrs.render_end.status = RENDER_INVALID_PAGE; ERRORPRINTF("Cannot render an invalid page"); } default: break; } listeners.broadcast(this, EVENT_RENDERING_END, &attrs); }
inline int decrease_fd_usage(hash_table_t * ht, int fd) { item_t * item = hash_table_find(ht, &fd); fd_usage_t * fd_usage; if (item == NULL) { //was not opened before ERRORPRINTF("Trying to decrease usage of fd:%d, which doesn't exist!\n", fd); assert(1 == 0); return -1; } else { //we have it already fd_usage = hash_table_entry(item, fd_usage_t, item); fd_usage->usage--; if (fd_usage->usage == 0) { hash_table_remove(ht, &fd); return 1; } } return 0; }
void PaceFilter::send_Next() { switch(state) { case P_DOWN: want_next = true; break; case P_IDLE: state = P_BUSY; timer.start(last_len*byte_delay + delay); break; case P_BUSY: ERRORPRINTF(t, E_WARNING, "send_next on busy pacer?"); break; } }
void PDFRenderTask::execute() { // don't execute the prerender task if the page is out of date if (is_page_out_of_date()) { return; } PDFRenderer *renderer = doc_ctrl->get_renderer(); // estimate whether the page has been cached // it is necessary here although there is same estimation // in main thread, because the same page might be constructed // in other tasks. if (page == 0) { page = doc_ctrl->get_page(page_number); if (page == 0) { page = renderer->gen_page(page_number, page_render_attr); } } //assert(page); if (page == 0) { ERRORPRINTF("Cannot Create New Page"); return; } // set the reference id, this operation is thread-safe now // NOTE: this function must be called before setting render attributes // because the main thread would update the ref id if the render attributes // changes. page->set_ref_id(ref_id); // if it is ZOOM_AUTO_CROP mode, it means it is necessary to get the content // area of the page double real_zoom = page_render_attr.get_real_zoom_value(); if (real_zoom == PLUGIN_ZOOM_TO_CROP_BY_PAGE || real_zoom == PLUGIN_ZOOM_TO_CROP_BY_WIDTH) { RenderArea content_area; if (!page->get_content_area(renderer, content_area)) { ERRORPRINTF("Cannot get content area of page:%d", page_number); return; } PDFRenderAttributes origin_attr = page_render_attr; renderer->calc_real_zoom(page_number, origin_attr, page_render_attr); real_zoom = page_render_attr.get_real_zoom_value(); } // if the page is cached and the bitmap has been rendered // calculate the delta value. Becuase the old bitmap would // be destroyed and new one is going to be rendered in the following // step int page_len = static_cast<int>(page->length()); page_len = static_cast<int>(PDFPage::try_calc_length(real_zoom, doc_ctrl->get_page_crop_width(page_number), doc_ctrl->get_page_crop_height(page_number))) - page_len; PDFPage::RenderStatus cur_status = page->get_render_status(); if (!(page->get_render_attr() == page_render_attr)) { // if the render attributes change, re-render the page // DO NOT update the render setting here, because it might // change the length of page // DO NOT change the status of page at this moment cur_status = PDFPage::RENDER_STOP; } bool render_done = true; // render bitmap if (cur_status != PDFPage::RENDER_DONE) { TRACE("Task, Render Page:%d, Ref ID:%d, Current Task:%p\n\n", page_number, ref_id, this); // update the page cache to make sure there is enough memory // if page_len < 0, it means the page is going to shrink, the memory // must be enough // TODO. Add the page number as one parameter for making enough memory // The pages with lower priorites would be released. if (page_len > 0 && !PDFLibrary::instance().make_enough_memory(doc_ctrl, page_number, page_len)) { WARNPRINTF("Cannot make enough memory to implement rendering"); // notify uds that it is out of memory that the page rendering // is aborted renderer->handle_page_ready(render_result, page, TASK_RENDER_OOM); return; } // update the render status page->set_render_status(cur_status); // only set the render attributes page->set_render_attr(page_render_attr); render_done = page->render_splash_map(renderer , static_cast<void*>(this)); // render the text page when the render is done if (render_done) { page->render_text(renderer); } } if (render_done) { // set the render status at last page->set_render_status(PDFPage::RENDER_DONE); if (render_result != 0) { // set the page into render result render_result->set_page(page); } // notify uds that the page is ready renderer->handle_page_ready(render_result, page, TASK_RENDER_DONE); } else { if (render_result != 0 && is_aborted()) { // if the task is aborted, set the render result to "Discard" render_result->set_discard(true); } else { renderer->handle_page_ready(render_result, page, TASK_RENDER_OOM); } } }
void EIBNetIPTunnel::error_cb () { ERRORPRINTF (t, E_ERROR | 20, "Communication error: %s", strerror(errno)); errored(); }
int main (int ac, char *ag[]) { int index; pth_init (); argp_parse (&argp, ac, ag, ARGP_IN_ORDER, &index, &arg); // if you ever want this to be fatal, doing it here would be too late if (getuid () == 0) ERRORPRINTF (arg.tracer(), E_WARNING | 20, 0, "EIBD should not run as root"); signal (SIGPIPE, SIG_IGN); if (arg.daemon) { int fd = open (arg.daemon, O_WRONLY | O_APPEND | O_CREAT, FILE_MODE); if (fd == -1) die ("Can not open file %s", arg.daemon); int i = fork (); if (i < 0) die ("fork failed"); if (i > 0) exit (0); close (1); close (2); close (0); dup2 (fd, 1); dup2 (fd, 2); close (fd); setsid (); } FILE *pidf; if (arg.pidfile) if ((pidf = fopen (arg.pidfile, "w")) != NULL) { fprintf (pidf, "%d", getpid ()); fclose (pidf); } signal (SIGINT, SIG_IGN); signal (SIGTERM, SIG_IGN); // main loop #ifdef HAVE_SYSTEMD sd_notify(0,"READY=1"); #endif int sig; if (! arg.stop_now) do { sigset_t t1; sigemptyset (&t1); sigaddset (&t1, SIGINT); sigaddset (&t1, SIGHUP); sigaddset (&t1, SIGTERM); pth_sigwait (&t1, &sig); if (sig == SIGHUP && arg.daemon) { int fd = open (arg.daemon, O_WRONLY | O_APPEND | O_CREAT, FILE_MODE); if (fd == -1) { ERRORPRINTF (arg.tracer(), E_ERROR | 21, 0, "can't open log file %s", arg.daemon); continue; } close (1); close (2); dup2 (fd, 1); dup2 (fd, 2); close (fd); } } while (sig == SIGHUP); #ifdef HAVE_SYSTEMD sd_notify(0,"STOPPING=1"); #endif signal (SIGINT, SIG_DFL); signal (SIGTERM, SIG_DFL); #ifdef HAVE_GROUPCACHE DeleteGroupCache (); #endif arg.free_l3(); if (arg.pidfile) unlink (arg.pidfile); pth_yield (0); pth_yield (0); pth_yield (0); pth_yield (0); pth_exit (0); return 0; }
void FT12LowLevelDriver::Run (pth_sem_t * stop1) { CArray last; int i; uchar buf[255]; pth_event_t stop = pth_event (PTH_EVENT_SEM, stop1); pth_event_t input = pth_event (PTH_EVENT_SEM, &in_signal); pth_event_t timeout = pth_event (PTH_EVENT_RTIME, pth_time (0, 100000)); while (pth_event_status (stop) != PTH_STATUS_OCCURRED) { pth_event_isolate (input); pth_event_isolate (timeout); if (mode == 0) pth_event_concat (stop, input, NULL); if (mode == 1) pth_event_concat (stop, timeout, NULL); i = pth_read_ev (fd, buf, sizeof (buf), stop); if (i > 0) { t->TracePacket (0, this, "Recv", i, buf); akt.setpart (buf, akt (), i); } while (akt.len () > 0) { if (akt[0] == 0xE5 && mode == 1) { pth_sem_dec (&in_signal); inqueue.get (); if (inqueue.isempty ()) pth_sem_set_value (&send_empty, 1); akt.deletepart (0, 1); mode = 0; repeatcount = 0; } else if (akt[0] == 0x10) { if (akt () < 4) break; if (akt[1] == akt[2] && akt[3] == 0x16) { uchar c1 = 0xE5; t->TracePacket (0, this, "Send Ack", 1, &c1); if(write (fd, &c1, 1) != 1) { ERRORPRINTF (t, E_ERROR | 10, this, "write error (%s)", strerror(errno)); break; } if ((akt[1] == 0xF3 && !recvflag) || (akt[1] == 0xD3 && recvflag)) { //right sequence number recvflag = !recvflag; } if ((akt[1] & 0x0f) == 0) { const uchar reset[1] = { 0xA0 }; CArray *c = new CArray (reset, sizeof (reset)); t->TracePacket (0, this, "RecvReset", *c); outqueue.put (c); pth_sem_inc (&out_signal, TRUE); } } akt.deletepart (0, 4); } else if (akt[0] == 0x68) { int len; uchar c1; if (akt () < 7) break; if (akt[1] != akt[2] || akt[3] != 0x68) { //receive error, try to resume akt.deletepart (0, 1); continue; } if (akt () < akt[1] + 6U) break; c1 = 0; for (i = 4; i < akt[1] + 4U; i++) c1 += akt[i]; if (akt[akt[1] + 4] != c1 || akt[akt[1] + 5] != 0x16) { len = akt[1] + 6; //Forget wrong short frame akt.deletepart (0, len); continue; } c1 = 0xE5; t->TracePacket (0, this, "Send Ack", 1, &c1); i = write (fd, &c1, 1); if ((akt[4] == 0xF3 && recvflag) || (akt[4] == 0xD3 && !recvflag)) { if (CArray (akt.array () + 5, akt[1] - 1) != last) { TRACEPRINTF (t, 0, this, "Sequence jump"); recvflag = !recvflag; } else TRACEPRINTF (t, 0, this, "Wrong Sequence"); } if ((akt[4] == 0xF3 && !recvflag) || (akt[4] == 0xD3 && recvflag)) { recvflag = !recvflag; CArray *c = new CArray; len = akt[1] + 6; c->setpart (akt.array () + 5, 0, len - 7); last = *c; outqueue.put (c); pth_sem_inc (&out_signal, TRUE); } // XXX TODO otherwise set 'len' to what? Or continue? akt.deletepart (0, len); } else //Forget unknown byte akt.deletepart (0, 1); } if (mode == 1 && pth_event_status (timeout) == PTH_STATUS_OCCURRED) mode = 0; if (mode == 0 && !inqueue.isempty ()) { const CArray & c = inqueue.top (); t->TracePacket (0, this, "Send", c); repeatcount++; i = pth_write_ev (fd, c.array (), c (), stop); if (i == c ()) { mode = 1; timeout = pth_event (PTH_EVENT_RTIME | PTH_MODE_REUSE, timeout, pth_time (0, 100000)); } } } pth_event_free (stop, PTH_FREE_THIS); pth_event_free (timeout, PTH_FREE_THIS); pth_event_free (input, PTH_FREE_THIS); }
void EIBnetServer::start() { struct sockaddr_in baddr; LinkConnectClientPtr mcast_conn; TRACEPRINTF (t, 8, "Open"); sock_mac = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock_mac < 0) { ERRORPRINTF (t, E_ERROR | 27, "Lookup socket creation failed"); goto err_out0; } memset (&baddr, 0, sizeof (baddr)); #ifdef HAVE_SOCKADDR_IN_LEN baddr.sin_len = sizeof (baddr); #endif baddr.sin_family = AF_INET; baddr.sin_addr.s_addr = htonl (INADDR_ANY); baddr.sin_port = single_port ? htons(port) : 0; sock = new EIBNetIPSocket (baddr, 1, t); if (!sock) { ERRORPRINTF (t, E_ERROR | 41, "EIBNetIPSocket creation failed"); goto err_out1; } sock->SetInterface(interface); if (!sock->init ()) goto err_out2; sock->on_recv.set<EIBnetServer,&EIBnetServer::recv_cb>(this); sock->on_error.set<EIBnetServer,&EIBnetServer::error_cb>(this); sock->recvall = 1; Port = sock->port (); mcast_conn = LinkConnectClientPtr(new LinkConnectClient(std::dynamic_pointer_cast<EIBnetServer>(shared_from_this()), router_cfg, t)); mcast = EIBnetDriverPtr(new EIBnetDriver (mcast_conn, multicastaddr, single_port ? 0 : port, interface)); if (!mcast) { ERRORPRINTF (t, E_ERROR | 42, "EIBnetDriver creation failed"); goto err_out2; } mcast_conn->set_driver(mcast); if (!mcast_conn->setup ()) goto err_out3; if (route && !static_cast<Router &>(router).registerLink(mcast_conn)) goto err_out3; TRACEPRINTF (t, 8, "Opened"); Server::start(); return; err_out3: mcast.reset(); err_out2: delete sock; sock = NULL; err_out1: close (sock_mac); sock_mac = -1; err_out0: Server::stop(); }
void CEMIDriver::reset_timer_cb(ev::timer &w, int revents) { ERRORPRINTF(t, E_ERROR | 44, "reset timed out"); errored(); }
EIBnetDriver::EIBnetDriver (LinkConnectClientPtr c, std::string& multicastaddr, int port, std::string& intf) : SubDriver(c) { struct sockaddr_in baddr; struct ip_mreq mcfg; sock = 0; t->setAuxName("driver"); TRACEPRINTF (t, 8, "OpenD"); if (GetHostIP (t, &maddr, multicastaddr) == 0) { ERRORPRINTF (t, E_ERROR | 11, "Addr '%s' not resolvable", multicastaddr); goto err_out; } if (port) { maddr.sin_port = htons (port); memset (&baddr, 0, sizeof (baddr)); #ifdef HAVE_SOCKADDR_IN_LEN baddr.sin_len = sizeof (baddr); #endif baddr.sin_family = AF_INET; baddr.sin_addr.s_addr = htonl (INADDR_ANY); baddr.sin_port = htons (port); sock = new EIBNetIPSocket (baddr, 1, t); if (!sock->SetInterface(intf)) goto err_out; if (!sock->init ()) goto err_out; sock->on_recv.set<EIBnetDriver,&EIBnetDriver::recv_cb>(this); sock->on_error.set<EIBnetDriver,&EIBnetDriver::error_cb>(this); } else { EIBnetServer &parent = *std::static_pointer_cast<EIBnetServer>(server); maddr.sin_port = parent.Port; sock = parent.sock; } mcfg.imr_multiaddr = maddr.sin_addr; mcfg.imr_interface.s_addr = htonl (INADDR_ANY); if (!sock->SetMulticast (mcfg)) goto err_out; /** This causes us to ignore multicast packets sent by ourselves */ if (!GetSourceAddress (t, &maddr, &sock->localaddr)) goto err_out; sock->localaddr.sin_port = std::static_pointer_cast<EIBnetServer>(server)->Port; sock->recvall = 2; TRACEPRINTF (t, 8, "OpenedD"); return; err_out: if (sock && port) delete (sock); sock = 0; return; }
int main (int ac, char *ag[]) { int index; Queue < Server * >server; Server *s; Layer2Interface *l2; Layer3 *l3; #ifdef HAVE_EIBNETIPSERVER EIBnetServer *serv = 0; #endif memset (&arg, 0, sizeof (arg)); arg.addr = 0x0001; arg.errorlevel = LEVEL_WARNING; argp_parse (&argp, ac, ag, 0, &index, &arg); if (index > ac - 1) die ("url expected"); if (index < ac - 1) die ("unexpected parameter"); if (arg.port == 0 && arg.name == 0 && arg.serverip == 0) die ("No listen-address given"); signal (SIGPIPE, SIG_IGN); pth_init (); Trace t; t.SetTraceLevel (arg.tracelevel); t.SetErrorLevel (arg.errorlevel); /* if (getuid () == 0) ERRORPRINTF (&t, 0x37000001, 0, "EIBD should not run as root"); */ if(arg.eibnetname) { if(arg.eibnetname[0] == '=') arg.eibnetname++; if(strlen(arg.eibnetname) >= 30) die("EIBnetServer/IP name can't be longer then 30 char"); } if (arg.daemon) { int fd = open (arg.daemon, O_WRONLY | O_APPEND | O_CREAT, FILE_MODE); if (fd == -1) die ("Can not open file %s", arg.daemon); int i = fork (); if (i < 0) die ("fork failed"); if (i > 0) exit (0); close (1); close (2); close (0); dup2 (fd, 1); dup2 (fd, 2); close (fd); setsid (); } FILE *pidf; if (arg.pidfile) if ((pidf = fopen (arg.pidfile, "w")) != NULL) { fprintf (pidf, "%d", getpid ()); fclose (pidf); } l2 = Create (ag[index], arg.backendflags, &t); if (!l2 || !l2->init ()) die ("initialisation of the backend failed"); l3 = new Layer3 (l2, &t); if (arg.port) { s = new InetServer (l3, &t, arg.port); if (!s->init ()) die ("initialisation of the knxd inet protocol failed"); server.put (s); } if (arg.name) { s = new LocalServer (l3, &t, arg.name); if (!s->init ()) die ("initialisation of the knxd unix protocol failed"); server.put (s); } #ifdef HAVE_EIBNETIPSERVER serv = startServer (l3, &t, arg.eibnetname); #endif #ifdef HAVE_GROUPCACHE if (!CreateGroupCache (l3, &t, arg.groupcache)) die ("initialisation of the group cache failed"); #endif signal (SIGINT, SIG_IGN); signal (SIGTERM, SIG_IGN); int sig; do { sigset_t t1; sigemptyset (&t1); sigaddset (&t1, SIGINT); sigaddset (&t1, SIGHUP); sigaddset (&t1, SIGTERM); pth_sigwait (&t1, &sig); if (sig == SIGHUP && arg.daemon) { int fd = open (arg.daemon, O_WRONLY | O_APPEND | O_CREAT, FILE_MODE); if (fd == -1) { ERRORPRINTF (&t, 0x27000002, 0, "can't open log file %s", arg.daemon); continue; } close (1); close (2); dup2 (fd, 1); dup2 (fd, 2); close (fd); } } while (sig == SIGHUP); signal (SIGINT, SIG_DFL); signal (SIGTERM, SIG_DFL); while (!server.isempty ()) delete server.get (); #ifdef HAVE_EIBNETIPSERVER if (serv) delete serv; #endif #ifdef HAVE_GROUPCACHE DeleteGroupCache (); #endif delete l3; if (Cleanup) Cleanup (); if (arg.pidfile) unlink (arg.pidfile); pth_exit (0); return 0; }