/* Cleanly stop the emulator. */ void do_stop(void) { quited = 1; plat_delay_ms(100); pc_close(thMain); thMain = NULL; }
static void cmd_get_libs(int pid, int sock) { struct mapiipcbuf buf; static char path[2048] = { '\0' }; char *str, *path_; long file_size; conf_category_t *conf; if (path[0] == '\0') { if ((conf = pc_load(mapid_conf)) != NULL) { str = pc_get_param(pc_get_category(conf, ""), "libs"); strncpy(path, str, sizeof(char) * 2048); strncpy((char *)buf.data, path, sizeof(char) * 2048); buf.cmd = GET_LIBS_ACK; if (log_to_file) { path_ = strdup(path); file_size = acquire_write_lock(log_fd_info); write_libraries(log_fd_info, path_); release_write_lock(log_fd_info, file_size); free(path_); } if (log_to_syslog) { path_ = strdup(path); syslog_libraries(path_); free(path_); } pc_close(conf); } else { buf.cmd = GET_LIBS_NACK; } } else { strncpy((char *)buf.data, path, sizeof(char) * 2048); buf.cmd = GET_LIBS_ACK; } buf.mtype = pid; mapiipc_daemon_write(&buf, sock); }
static void cmd_get_libpath(int pid, int sock) //Create a new flow //dev = device //if = IPC id used to send ack message back to client { struct mapiipcbuf buf; char *path, *p; static char newpath[BUFSIZE] = { '\0' }; char *np = newpath; char pwd[BUFSIZE]; int size= BUFSIZE; int first = 1; conf_category_t *conf; buf.cmd = GET_LIBPATH_ACK; if (newpath[0] == '\0') { if ((conf = pc_load(mapid_conf)) != NULL) { path = pc_get_param(pc_get_category(conf, ""), "libpath"); //Add current path of mapid to relative paths if (getcwd(pwd, BUFSIZE) == NULL) buf.cmd = GET_LIBPATH_NACK; else { while ((p = strchr(path, ':')) != NULL) { *p = '\0'; if (!first) { *np = ':'; np++; } if (path[0] != '/') { snprintf(np, size, "%s/", pwd); np += strlen(pwd) + 1; size -= strlen(pwd) + 1; } snprintf(np, size, "%s", path); np += strlen(path); size -= strlen(path); path = p + 1; first = 0; } if (!first) { *np = ':'; np++; } if (path[0] != '/') { snprintf(np, size, "%s/", pwd); np += strlen(pwd) + 1; size -= strlen(pwd) + 1; } snprintf(np, size, "%s", path); np += strlen(path); size -= strlen(path); //Copy path to buffer strncpy((char *)buf.data, newpath, sizeof(char) * 2048); } pc_close(conf); } else { buf.cmd = GET_LIBPATH_NACK; } } else { strncpy((char *)buf.data, newpath, sizeof(char) * 2048); } buf.mtype = pid; mapiipc_daemon_write(&buf, sock); }
static void * load_drivers() { conf_category_entry_t *cat=NULL; conf_parameter_t *p; char *device= NULL, *driver= NULL, *drvpath= NULL, *format= NULL; char *description= NULL, *alias= NULL, *trace_dir= NULL, *link_speed=NULL, *devgroupstr=NULL, *mpls=NULL, *vlan=NULL, *local=NULL; void *handle; mapidrv *drv; int err; conf_category_t *conf; mapidrv *drvlist2= NULL; mapidrv *lok= NULL; if ((conf = pc_load(mapid_conf)) != NULL) { cat = pc_get_category(conf, ""); local=pc_get_param(cat, "local"); drvpath = pc_get_param(cat, "drvpath"); cat = pc_get_category(conf, "driver"); //Loop through drivers while (cat != NULL) { device=pc_get_param(cat, "device"); driver=pc_get_param(cat, "driver"); description=pc_get_param(cat, "description"); alias=pc_get_param(cat, "alias"); trace_dir=pc_get_param(cat, "trace_dir"); link_speed=pc_get_param(cat, "link_speed"); devgroupstr=pc_get_param(cat, "devgroup"); mpls=pc_get_param(cat, "mpls"); vlan=pc_get_param(cat, "vlan"); if (device && strlen(device) > 0 && driver && strlen(driver) > 0) { if ((handle = load_driver(drvpath, driver)) != NULL) { drv = malloc(sizeof(mapidrv)); drv->device = strdup(device); if (drvlist2!=NULL) { lok->next = drv; lok = lok->next; } else { drvlist2 = drv; lok = drv; } drv->next = NULL; drv->handle = handle; drv->name = strdup(driver); drv->format = -1; drv->devid = deviceid++; drv->offline=0; drv->active = 0; drv->offline_status = DEVICE_ONLINE; if (description!=NULL) drv->description = strdup(description); else drv->description=strdup("No description"); if (alias!=NULL) drv->alias = strdup(alias); else drv->alias=strdup("No alias"); if (trace_dir != NULL) drv->trace_dir = strdup(trace_dir); else drv->trace_dir = NULL; if (link_speed!=NULL) drv->link_speed = atoi(link_speed); else drv->link_speed = 0; if (mpls!=NULL) drv->mpls = atoi(mpls); else drv->mpls = 0; if (vlan!=NULL) drv->vlan = atoi(vlan); else drv->vlan = 0; //Call driver add_device mapidrv_add_device = get_drv_funct(drv->handle, "mapidrv_add_device"); err = mapidrv_add_device(device, -1, drv->devid, gflist, drv->trace_dir); if (!err) drv->active = 1; //Quick fix for a bug in the config file parser if (format!=NULL) { device[0] = '\0'; driver[0] = '\0'; if (description!=NULL) description[0] = '\0'; } } } cat = cat->next; } //Check file formats cat = pc_get_category(conf, "format"); //Loop through drivers while (cat != NULL) { p = cat->params; if ((strcmp(p->name, "format") == 0) && (p->next != NULL) && (strcmp(p->next->name, "driver") == 0)) { format = p->value; driver = p->next->value; if ((p->next->next!=NULL) && (strcmp(p->next->next->name, "description") == 0)) description = p->next->next->value; else description = NULL; } else { cat = cat->next; continue; } if (strlen(format) > 0 && strlen(driver) > 0) { //Check to see if driver is allready loaded for (drv = drvlist2; drv != NULL; drv = drv->next) { if (strcmp(driver, drv->name) == 0) { drv->format = get_format(format); break; } } if (drv == NULL) { //Load new driver if ((handle = load_driver(drvpath, driver)) != NULL) { drv = malloc(sizeof(mapidrv)); drv->format = get_format(format); drv->device = strdup(format); if (drvlist2!=NULL) { lok->next = drv; lok=lok->next; } else { drvlist2 = drv; lok = drv; } drv->next=NULL; drv->handle = handle; drv->offline = 1; drv->active = 0; drv->name = strdup(driver); if (description!=NULL) drv->description = strdup(description); else drv->description=strdup("No description"); if (link_speed!=NULL) drv->link_speed = atoi(link_speed); else drv->link_speed = 0; if (mpls!=NULL) drv->mpls = atoi(mpls); else drv->mpls = 0; if (vlan!=NULL) drv->vlan = atoi(vlan); else drv->vlan = 0; } } //Quick fix for a bug in the config file parser if (format!=NULL) { if (device!=NULL) device[0] = '\0'; if (driver!=NULL) driver[0] = '\0'; if (description!=NULL) description[0] = '\0'; } } cat = cat->next; } pc_close(conf); } return drvlist2; }
static void mapidcom() //Communicates with clients through IPC { fd_set active_fd_set; // active file descriptor list fd_set read_fd_set; // temp file descriptor list for select() int fdmax; // maximum file descriptor number int yes = 1; // for setsockopt() SO_REUSEADDR, below struct sockaddr_un mapidaddr; struct sockaddr_un remoteaddr; struct mapiipcbuf qbuf; socklen_t addrlen; int nbytes, len, s; struct client *cl= NULL; flist_node_t *tmpnode; conf_category_entry_t *cat=NULL; char *local; struct group *mapi_group; conf_category_t *conf; mapidsocket=strdup(MAPIDSOCKGLOBAL); if ((conf = pc_load(mapid_conf)) != NULL) { cat = pc_get_category(conf, ""); local=pc_get_param(cat, "local"); if (local!=NULL && strcmp(local, "1")==0) { free(mapidsocket); mapidsocket=printf_string(MAPIDSOCKHOME, getenv("HOME") ); } pc_close(conf); } // create the listener socket if ((listenerfd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { DEBUG_CMD(Debug_Message("ERROR: socket: %s", strerror(errno))); exit(EXIT_FAILURE); } // avoid "address already in use" error message if (setsockopt(listenerfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { DEBUG_CMD(Debug_Message("ERROR: setsockopt: %s", strerror(errno))); exit(EXIT_FAILURE); } // set up the address we will be binding to memset(&mapidaddr, 0, sizeof (mapidaddr)); mapidaddr.sun_family = AF_LOCAL; memcpy(mapidaddr.sun_path, mapidsocket, strlen(mapidsocket)+1); unlink(mapidsocket); len = sizeof mapidaddr.sun_family + strlen(mapidaddr.sun_path); if (bind(listenerfd, (struct sockaddr *) &mapidaddr, len)) { DEBUG_CMD(Debug_Message("ERROR: bind: %s", strerror(errno))); exit(EXIT_FAILURE); } // allow any member of our own group to connect chmod(mapidsocket, S_IRWXU | S_IRWXG); // if a mapi user group exists, set group permissions accordingly, // otherwise the group ID will be equal to the user ID of the user that // invoked mapid mapi_group = getgrnam(MAPI_GROUP_NAME); if (mapi_group != NULL) { chown(mapidsocket, -1, mapi_group->gr_gid); } if (listen(listenerfd, BACKLOG) == -1) { DEBUG_CMD(Debug_Message("ERROR: listen: %s", strerror(errno))); exit(EXIT_FAILURE); } FD_ZERO (&active_fd_set); // add the listener to the active set FD_SET (listenerfd, &active_fd_set) ; // keep track of the biggest file descriptor fdmax = listenerfd; // so far, it's just this one // wait for commands from the mapi stub, for ever... while (1) { read_fd_set = active_fd_set; // copy it if (select(fdmax + 1, &read_fd_set, NULL, NULL, NULL) == -1) { DEBUG_CMD(Debug_Message("ERROR: select: %s", strerror(errno))); break; } // run through the existing connections for (s = 0; s <= fdmax; s++) { if (FD_ISSET (s, &read_fd_set)) { // connection on the original listener socket if (s == listenerfd) { addrlen = sizeof (remoteaddr); if ((newfd = accept(listenerfd, (struct sockaddr *) &remoteaddr, &addrlen)) == -1) { DEBUG_CMD(Debug_Message("accept: %s", strerror(errno))); } else { FD_SET (newfd, &active_fd_set) ; // add to active set if (newfd > fdmax) { // keep track of the maximum fdmax = newfd; } } } // handle data from an existing client else { if ((nbytes = recv (s, &qbuf, MAX_SEND_SIZE, 0)) <= 0) { if (nbytes == 0) { // connection closed - find client's pid while(__sync_lock_test_and_set(&clientlist_lock,1)); tmpnode = (flist_node_t *) flist_head (clientlist); cl = NULL; while (tmpnode != NULL) { if (((struct client *) tmpnode->data)->sock == s) { cl = (struct client *) tmpnode->data; break; } tmpnode = flist_next (tmpnode); } clientlist_lock = 0; if (cl == NULL) {/* This is not interesting, as it will occur upon requests from clients without flows etc. WARNING_CMD (printf ("WARNING: Zero bytes from socket %d [%s:%d]\n", s, __FILE__, __LINE__)); */ /* shouldn't really exit here? * this will cause the program to exit on errors with an empty * client-list which isn't really an error (IMHO) */ //exit(EXIT_FAILURE); } else { while(__sync_lock_test_and_set(&clientlist_lock,1)); //clean up any remaining flows tmpnode = (flist_node_t *) flist_head (cl->flowlist); while (tmpnode != NULL) { cleanup_flow ((struct flow *) tmpnode->data); tmpnode = flist_next (tmpnode); } tmpnode = (flist_node_t *) flist_head (cl->devicelist); while (tmpnode != NULL) { mapidrv_delete_device = get_drv_funct (tmpnode->data, "mapidrv_delete_device"); mapidrv_delete_device (tmpnode->id); tmpnode = flist_next (tmpnode); } flist_destroy (cl->flowlist); flist_destroy (cl->devicelist); free(cl->devicelist); free (cl->flowlist); //remove this client from global client list free(flist_remove (clientlist, cl->pid)); clientlist_lock = 0; } } else { DEBUG_CMD(Debug_Message("WARNING: recv: %s at", strerror (errno))); } close (s); FD_CLR (s, &active_fd_set); // remove it from active set } else { // we got some data from a client: process request switch (qbuf.cmd) { case GET_LIBS: cmd_get_libs (qbuf.pid, s); break; case GET_LIBPATH: cmd_get_libpath (qbuf.pid, s); break; case CREATE_FLOW: cmd_create_flow ((char *)qbuf.data, qbuf.pid, qbuf.uid, s); break; case CLOSE_FLOW: cmd_close_flow (qbuf.fd, qbuf.pid, s, 1); break; case GET_FLOW_INFO: cmd_get_flow_info (qbuf.fd, qbuf.pid, s); break; case GET_FUNCTION_INFO: cmd_get_function_info (qbuf.fd, qbuf.fid, qbuf.pid, s); break; case GET_NEXT_FUNCTION_INFO: cmd_get_next_function_info (qbuf.fd, qbuf.fid, qbuf.pid, s); break; case GET_NEXT_FLOW_INFO: cmd_get_next_flow_info (qbuf.fd, qbuf.pid, s); break; case GET_NEXT_DEVICE_INFO: cmd_get_next_device_info (qbuf.fd, qbuf.pid, s); break; case GET_DEVICE_INFO: cmd_get_device_info (qbuf.fd, qbuf.pid, s); break; case MAPI_STATS: cmd_stats ((char *)qbuf.data, qbuf.pid, qbuf.uid, s); break; case APPLY_FUNCTION: cmd_apply_function (&qbuf, qbuf.pid, s); break; case READ_RESULT: cmd_read_results (qbuf.fd, qbuf.fid, qbuf.pid, s); break; case CONNECT: cmd_connect (qbuf.fd, qbuf.pid, s); break; case CREATE_FLOW_ACK: case APPLY_FUNCTION_ACK: case READ_RESULT_ACK: case CONNECT_ACK: case CLOSE_FLOW_ACK: case SET_AUTHDATA_ACK: break; case READ_ERROR_ACK: break; case ERROR_ACK: break; case CREATE_OFFLINE_DEVICE: cmd_create_offline_device ((char *)qbuf.data, qbuf.fid, qbuf.pid, s); break; case CREATE_OFFLINE_DEVICE_ACK: break; case START_OFFLINE_DEVICE: cmd_start_offline_device ((char *)qbuf.data, qbuf.pid, s); break; case START_OFFLINE_DEVICE_ACK: break; case DELETE_OFFLINE_DEVICE: cmd_delete_offline_device ((char *)qbuf.data, qbuf.pid, s); break; case DELETE_OFFLINE_DEVICE_ACK: break; case CREATE_OFFLINE_FLOW_ACK: break; case LOAD_LIBRARY: cmd_load_library ((char *)qbuf.data, qbuf.pid, s); default: break; } } } } } // for } // while(1) }