Ejemplo n.º 1
0
int main(int argc, char * argv[]) {

	tokenitem * locklist = NULL;

	spread_connect();

	while (1) {
		tokenitem * t;
		spread_receive();

		char * token = get_token();
		char * sender = get_sender();

		switch (get_message_type()) {
		case MSG_REQUEST_WRITE:
			// send lock or list of open read and write locks
			printf("%s requests write to %s\n", sender, token);
			
			t = token_find_add(&locklist, token);
			if (!t->readlocks && !t->writelocks) {
				addlock(&(t->writelocks), sender);
				spread_send(sender, "ack", token);
			} else {
				spread_send_list(sender, "client_list", token, format_locklist(t, 1));
			}
			break;
		case MSG_REQUEST_READ:
			// send lock or list of open write locks
			printf("%s requests read to %s\n", sender, token);

			t = token_find_add(&locklist, token);
			if (!t->writelocks) {
				addlock(&(t->readlocks), sender);
				spread_send(sender, "ack", token);
			} else {
				spread_send_list(sender, "client_list", token, format_locklist(t, 0));
			}
			break;
		case MSG_REVOKE_DONE:
			//update tables(this client has write, reads are gone) -> send ack
			printf("%s says revoke is done for %s\n", sender, token);
			t = token_find_add(&locklist, token);
			if (t->writelocks) {
				free_locklist(t->writelocks);
				t->writelocks = NULL;
			}
			if (t->readlocks) {
				free_locklist(t->readlocks);
				t->readlocks = NULL;
			}
			addlock(&(t->writelocks), sender);
			spread_send(sender, "ack", token);
			break;
		case MSG_DOWNGRADE_DONE:
			//updates tables(this client has read, writes are now reads) -> send ack
			printf("%s says downgrade is done for %s\n", sender, token);
			t = token_find_add(&locklist, token);
			if (t->writelocks) {
				movelocks(&(t->writelocks), &(t->readlocks));
			}
			if (t->readlocks) {
				removelock(&(t->readlocks), sender);
			}
			addlock(&(t->readlocks), sender);
			spread_send(sender, "ack", token);
			break;
		case MSG_CLOSE:
			//remove any locks for this token for this client
			printf("%s says it is closing %s\n", sender, token);

			t = token_find(&locklist, token);
			if (t) {
				if (t->readlocks) {
					removelock(&(t->readlocks), sender);
				}
				if (t->writelocks) {
					removelock(&(t->writelocks), sender);
				}
				if (!t->readlocks && !t->writelocks) {
					removetoken(&locklist, token);
				}
			}
			spread_send(sender, "ack", token);
			break;
		case MSG_UNKNOWN:
			printf("unknown message! (%s, %s)\n", sender, token);
		}
		print_locklist(locklist);
	}

	return 0;
}
Ejemplo n.º 2
0
/*---------------------------------------
|                                       |
|            createlock()/2             |
|                                       |
+--------------------------------------*/
int createlock(char *filepath, int type)
{
    char	lockprimary[MAXPATHL],
            locksecondary[MAXPATHL],
            HostName[MAXPATHL];
    int	iter,
        lfd;
    FILE	*lkfptr,
            *fopen();


    (void) strcpy(lockprimary, filepath);
    (void) strcpy(locksecondary, filepath);
    (void) strcat(lockprimary, ".lock1");
    (void) strcat(locksecondary, ".lock2");


    /********************************
    *  Create secondary lock file.  *
    ********************************/

    for (iter = 0; iter < MAX_LOCK_ITER; iter++)
    {
        if ( (lfd = open(locksecondary, (O_CREAT|O_EXCL), 0666 )) >= 0 )
        {
            (void) close(lfd);
            iter = MAX_LOCK_ITER;
        }
        else
        {
            switch (type)
            {
            case INFO_LFILE:
                sleep(1);
                if ( (iter - 1) == MAX_LOCK_ITER )
                    return(ERROR);
                break;
            case DATA_LFILE:
                return(LOCKED_DFILE);
            default:
                return(ERROR);
            }
        }
    }


    /*******************************
    *   Create primary lock file.  *
    *******************************/

    if ( access(lockprimary, F_OK) == 0 )
    {
        if ( removelock(filepath) )
        {
            unlink(locksecondary);
            switch (type)
            {
            case DATA_LFILE:
                return(LOCKED_DFILE);
            case INFO_LFILE:
            default:
                return(ERROR);
            }
        }
    }

    if ( (lkfptr = fopen(lockprimary, "w")) == NULL )
    {
        unlink(locksecondary);
        return(ERROR);
    }

    (void) gethostname(HostName, sizeof(HostName));
    (void) fprintf( lkfptr, "%s %d\n", HostName, getpid() );
    (void) fclose(lkfptr);


    /********************************
    *  Remove secondary lock file.  *
    ********************************/

    if ( unlink(locksecondary) )
    {
        unlink(lockprimary);
        return(ERROR);
    }

    return(COMPLETE);
}
Ejemplo n.º 3
0
int main(int argc, char *argv[])
{
	const char *action = NULL;
	struct sigaction sa;

	ARGBEGIN {
	case 'l':
	case 'r':
	case 's':
		if (writefifo(fifofile, ARGC()) == -1)
			die("cannot write to fifo\n");
		exit(EXIT_SUCCESS);
	default:
		usage();
	} ARGEND;
	
	if (argc > 1)
		usage();

	if (getuid() != 0)
		die("only root can run this program\n");
	if (getlock(pidfile) == -1)
		die("cannot get exclusive lock\n");
	if (createfifo(fifofile, 0666) == -1)
		die("cannot create fifo\n");

	sa.sa_flags = SA_NOCLDSTOP;
	sa.sa_handler = catchsignal;
	sigemptyset(&sa.sa_mask);
	sigaction(SIGCHLD, &sa, NULL);

	signal(SIGINT, catchsignal);
	signal(SIGHUP, catchsignal);
	signal(SIGQUIT, catchsignal);
	signal(SIGTERM, catchsignal);
	signal(SIGKILL, catchsignal);
	signal(SIGPIPE, catchsignal);

	startserver(server, display);
	do {
		const char *user, *pass;
		char c;

		if (autologin && authenticate(autologin, NULL)) {
			autologin = NULL;
			goto login;
		}

		creategui();
		do {
			rungui(&user, &pass);
			if (!strcmp(user, "reboot"))
				action = rebootcmd;
			else if (!strcmp(user, "shutdown"))
				action = shutdowncmd;
		} while (!action && !authenticate(user, pass));
		destroygui();

		if (action)
			break;

login:		childpid = startsession(child, env);

		c = readfifo(fifofile);
		if (c == 'r')
			action = rebootcmd;
		else if (c == 's')
			action = shutdowncmd;
		else if (!c)
			while (childpid)
				sleep(10);

		stopsession();
	} while (!action);
	signal(SIGINT, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	signal(SIGQUIT, SIG_IGN);
	signal(SIGTERM, SIG_DFL);
	signal(SIGKILL, SIG_DFL);
	signal(SIGCHLD, SIG_DFL);
	signal(SIGPIPE, SIG_IGN);
	stopserver();

	removefifo(fifofile);
	removelock(pidfile);

	return system(action);
}
Ejemplo n.º 4
0
int main(int argc, char *argv[]) {
	char * message;
	lockitem * pendingclients = NULL; 

	if (argc < 3) {
		printf("usage: %s filename.txt [R|W]\n", argv[0]);
		return 0;
	}
	if (argv[2][0] == 'R') {
		last_message = MSG_REQUEST_READ;
		message = "request_read";
	} else if (argv[2][0] == 'W') {
		last_message = MSG_REQUEST_WRITE;
		message = "request_write";
	} else {
		printf("lock type must be R or W\n");
		return 0;
	}

	spread_connect();
	server = argv[1];

	spread_send(SERVER_NAME, message, server);

	set_alarm_handler();
	
	printf("SIGINT to quit\n");

	while (1) {
		spread_receive();
		char * token = get_token();
		char * sender = get_sender();
		char * list = get_list();

		switch(get_message_type()) {
		case MSG_REVOKE:
			printf("got a revoke message. quitting.\n");
			spread_send(sender, "ack", token);	
			exit(0);
			break;
		case MSG_DOWNGRADE:
			//TODO: write blocks to server
			//TODO: downgrade to read (currently no internal state of this)
			printf("got a downgrade message. doin it.\n");
			spread_send(sender, "ack", token);
			break;
		case MSG_CLIENT_LIST:
			if (last_message == MSG_REQUEST_WRITE) {
				printf("got a client list in response to a write request\n");
				parse_client_list(&pendingclients, list);
				last_message = MSG_REVOKE;
				message_others(pendingclients, "revoke", token);
			} else if (last_message == MSG_REQUEST_READ) {
				printf("got a client list in response to a read request\n");
				parse_client_list(&pendingclients, list);
				last_message = MSG_DOWNGRADE;
				message_others(pendingclients, "downgrade", token);
			} else {
				printf("don't know why we got a client list now\n");
			}
			break;
		case MSG_ACK:
			if (last_message == MSG_REQUEST_READ || last_message == MSG_REQUEST_WRITE ||
				last_message == MSG_DOWNGRADE_DONE || last_message == MSG_REVOKE_DONE) {
				printf("got lock!\n");
			} else  if (last_message == MSG_CLOSE) {
				//TODO: write blocks to server
				printf("got ack and quitting\n");
				return 0;
			} else if (last_message == MSG_DOWNGRADE) {
				printf("got ack for downgrade, removing from list\n");
				removelock(&pendingclients, sender);
				if (!pendingclients) {
					printf("downgrade is done!\n");
					last_message = MSG_DOWNGRADE_DONE;
					spread_send(SERVER_NAME, "downgrade_done", token);
				}
			} else if (last_message == MSG_REVOKE) {
				printf("got ack for revoke, removing from list\n");
				removelock(&pendingclients, sender);
				if (!pendingclients) {
					printf("revoke is done!\n");
					last_message = MSG_REVOKE_DONE;
					spread_send(SERVER_NAME, "revoke_done", token);
				}
			} else {
				printf("got ack for something other than close\n");
			}
			break;
		default: 
			printf("got a message for me, but what does it mean?\n");
		}
	}

	return 0;
}