Beispiel #1
0
static void* signal_thread(void* arg)
{
	pthread_attr_t tattr;           /* Used to set thread to detached mode */
	int err;                                        /* Indicates an error from sigwait */
	int signo;                                      /* The signal number that has been caught */
	pthread_t tid;                          /* ID of the thread that has been spawnned */

	// Make sure any threads that are spawned are detached, so the OS
	// can reclaim the resources in a timely fashion
	pthread_attr_init(&tattr);
	pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);

	for (;; ) {
		// Check directory for updates
		alarm(gperiod);

		// Block until signal has been caught
		err = sigwait(&mask, &signo);
		if (err != 0) {
			syslog(LOG_ERR, "sigwait failed");
			exit(1);
		}

		switch (signo) {
		case SIGHUP:
			// Finish transfers, remove all clients
			syslog(LOG_INFO, "Received SIGHUP");
			kill_clients(remove_client_pipes[1], "Server received SIGHUP; Disconnect all clients.");
			break;
		case SIGALRM:
			// See if directory has updated
			syslog(LOG_INFO, "Received SIGALRM");
			pthread_create(&tid, &tattr, send_updates, NULL);
			break;
		case SIGINT:
			// Mainly used when not running in daemon mode
			syslog(LOG_INFO, "Received SIGINT");
			kill_clients(remove_client_pipes[1], "Server received SIGINT; Disconnect all clients.");
			exit(0);
		case SIGTERM:
			syslog(LOG_INFO, "Received SIGTERM");
			kill_clients(remove_client_pipes[1], "Server received SIGTERM; Disconnect all clients.");
			exit(0);
		default:
			syslog(LOG_ERR, "Unexpected signal: %d", signo);
			break;
		}
	}
}
Beispiel #2
0
static void do_listen(char *port)
{
	struct addrinfo hints;
	struct addrinfo *result, *rp;
	int sfd, s, cfd;
	struct sockaddr_storage peer_addr;
	socklen_t peer_addr_len;
	int pid;

	if (!debug)
		signal_setup(SIGCHLD, clean_up);

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;

	s = getaddrinfo(NULL, port, &hints, &result);
	if (s != 0)
		pdie("getaddrinfo: error opening %s", port);

	for (rp = result; rp != NULL; rp = rp->ai_next) {
		sfd = socket(rp->ai_family, rp->ai_socktype,
			     rp->ai_protocol);
		if (sfd < 0)
			continue;

		if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
			break;

		close(sfd);
	}

	if (rp == NULL)
		pdie("Could not bind");

	freeaddrinfo(result);

	if (listen(sfd, backlog) < 0)
		pdie("listen");

	peer_addr_len = sizeof(peer_addr);

	do {
		cfd = accept(sfd, (struct sockaddr *)&peer_addr, &peer_addr_len);
		printf("connected!\n");
		if (cfd < 0 && errno == EINTR)
			continue;
		if (cfd < 0)
			pdie("connecting");

		pid = do_connection(cfd, &peer_addr, peer_addr_len);
		if (pid > 0)
			add_process(pid);

	} while (!done);

	kill_clients();
}
Beispiel #3
0
/* Handles the SIGINT, dispatching it to the clients */
static void sigint_signal_handler () {
    kill_clients();

    wait(5);

    int i = 0;
    for(; i < MAX_CLIENTS; i++){
        if(registered_clients[i] != 0){
            int p_status;
            kill(registered_clients[i], SIGINT);
            waitpid(registered_clients[i], &p_status, WUNTRACED);

            /* Close message queue */
            msgctl(client_msqid_from_pid(registered_clients[i]), IPC_RMID,0);
        }
    }


    fprintf(stdout, "[auctioneer] \x1b[31mQuitting... \x1b[0m \n");
    fflush(stdout);
    _exit(EXIT_SUCCESS);
}
Beispiel #4
0
int exploredir(struct direntrylist* list, const char* path)
{
	struct stat fattr;                      /* Used to store attributes of a file entry */
	struct direntry* list_entry;    /* Used to capture information about file entry */
	struct dirent** entries;        /* Stores each file entry's name and stuff */
	int n;                                                  /* How many file entries are in the directory */
	int i;                                                  /* Used to traverse file entries */

	// Alphabetize the entries in the directory since Linux is stupid
	// and doesn't do this by default, which Mac OS X does...
	if ((n = scandir(path, &entries, 0, alphasort)) < 0) {
		// Send error message to all clients and then exit
		kill_clients(remove_client_pipes[1], "Cannot open directory! ; Exiting now!");
		syslog(LOG_ERR, "Cannot open directory: %s", path);
		exit(1);
	}

	// Delete reference to current directory (.)
	free(entries[0]);
	// Delete reference to parent directory (..)
	free(entries[1]);

	// Start after . and ..
	i = 2;
	while (i < n) {
		list_entry = (struct direntry*)mempool_alloc(direntry_pool, sizeof(struct direntry));
		list_entry->next = NULL;
		memset(list_entry, 0, sizeof(list_entry));

		if (list_entry == NULL) {
			// Mempool has no free nodes and malloc failed
			kill_clients(remove_client_pipes[1], "Unrecoverable server error! ; Exiting now!");
			syslog(LOG_ERR, "Cannot malloc direntry");
			exit(1);
		}

		// Make sure absolute path is not too long
		if ((strlen(path) + strlen(entries[i]->d_name) + 1) >= PATH_MAX) {
			kill_clients(remove_client_pipes[1], "Unrecoverable server error! ; Exiting now!");
			syslog(LOG_ERR, "Path is too long.");
			exit(1);
		} else {
			strcpy(abspath, path);
			strcat(abspath, "/");
			strcat(abspath, entries[i]->d_name);
		}

		// Get the attributes of the file entry
		if (stat(abspath, &fattr) < 0) {
			kill_clients(remove_client_pipes[1], "Unrecoverable server error! ; Exiting now!");
			syslog(LOG_ERR, "Cannot get stats on file: %s", entries[i]->d_name);
			exit(1);
		}

		// Make sure just the file name is not too long
		if (strlen(entries[i]->d_name) > MAX_FILENAME) {
			syslog(LOG_ERR, "Filename is too long to be saved.");
			exit(1);
		}

		// Copy the file entry name into direntry representation
		strcpy(list_entry->filename, entries[i]->d_name);
		list_entry->attrs = fattr;

		// Add the list entry now
		add_direntry(list, list_entry);

		free(entries[i]);
		i++;
	}

	free(entries);

	return 0;
}