예제 #1
0
/* Cleanly stop the emulator. */
void
do_stop(void)
{
    quited = 1;

    plat_delay_ms(100);

    pc_close(thMain);

    thMain = NULL;
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
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;
}
예제 #5
0
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)
}