/**************************************************************************** * get_ticket * get a ticket from the license server * Results: 0 for success, -1 for failure */ int get_ticket() { char *response; char buf[MSGLEN]; if(have_ticket) /* don't be greedy */ return(0); sprintf(buf, "HELO %d", pid); /* compose request */ if ( (response = do_transaction(buf)) == NULL ) return(-1); /* parse the response and see if we got a ticket. * on success, the message is: TICK ticket-string * on failure, the message is: FAIL failure-msg */ if ( strncmp(response, "TICK", 4) == 0 ){ strcpy(ticket_buf, response + 5); /* grab ticket-id */ have_ticket = 1; /* set this flag */ narrate("got ticket", ticket_buf); return(0); } if ( strncmp(response,"FAIL",4) == 0) narrate("Could not get ticket",response); else narrate("Unknown message:", response); return(-1); } /* get_ticket */
/******************************************************************* * get_ticket * get a ticket from the license server * Result: 0 for scuccess, -1 for failure */ int get_ticket() { char *response; char buf[MSGLEN]; if(have_ticket) return 0; // dont' be greedy sprintf(buf,"HELLO %d",pid); if((response = do_transaction(buf)) == NULL) { return -1; } /* parse the response and if we got a ticket. * on success,the message is: TICK ticket-string * on failure,the message is: FAIL failute-msg */ if(strncmp(response,"TICK",4) == 0) { strcpy(ticket_buf,response + 5);; // grab ticket -id have_ticket = 1; // set the flag narrate("got ticket",ticket_buf); return 0; } if(strncmp(response,"FAIL",4) == 0) narrate("Could not get ticket",response); else narrate("Unknowm message:",response); return -1; }// get_ticket
// release_ticket: give a ticket back to the server int release_ticket() { char * response; char buf[MSGLEN]; if (!have_ticket) return(0); sprintf(buf, "GBYE %s", ticket_buf); if ((response = do_transcation(buf)) == NULL) return(-1); // parse the response and see if we give a ticket success if (strncmp(response, "THNX", 4) == 0) { have_ticket = 0; narrate("release a ticket", ""); return(0); } if (strncmp(response, "FAIL", 4) == 0) narrate("release failed", response+5); else narrate("Unknown message:", response); return(-1); }
/**************************************************************************** * release_ticket * Give a ticket back to the server * Results: 0 for success, -1 for failure */ int release_ticket() { char buf[MSGLEN]; char *response; if(!have_ticket) /* don't have a ticket */ return(0); /* nothing to release */ sprintf(buf, "GBYE %s", ticket_buf); /* compose message */ if ( (response = do_transaction(buf)) == NULL ) return(-1); /* examine response * success: THNX info-string * failure: FAIL error-string */ if ( strncmp(response, "THNX", 4) == 0 ){ narrate("released ticket OK",""); return 0; } if ( strncmp(response, "FAIL", 4) == 0) narrate("release failed", response+5); else narrate("Unknown message:", response); return(-1); } /* release_ticket */
// get_ticket: get a ticket from server int get_ticket() { char * response; char buf[MSGLEN]; if (have_ticket) return(0); sprintf(buf, "HELO %d", pid); if ((response = do_transcation(buf)) == NULL) return(-1); // parse the response and see if we got a ticket if (strncmp(response, "TICK", 4) == 0) { strcpy(ticket_buf, response+5); have_ticket = 1; printf("ticket_buf %s\n", ticket_buf); narrate("got ticket", ticket_buf); return(0); } if (strncmp(response, "FAIL", 4) == 0) narrate("Could not get ticket", response); else narrate("Unknown message:", response); return(-1); }
/******************************************************************* * do_validate * validate the ticket that hold on * Result: 0 for success, -1 for failure */ int do_validate() { char buf[BUFSIZ]; char *response; sprintf(buf,"VALD %s",ticket_buf); if((response = do_transaction(buf)) == NULL) return -1; /* parse the response and see if we the ticket is valid * on success, the message is: GOOD vaild-msg * on failure, the message is: FIAL failure-msg */ if(strncmp(response,"GOOD",4) == 0) { narrate("Validate success",ticket_buf); return 0; } if(strncmp(response,"FAIL",4) == 0) narrate("Invalid ticket",response); else narrate("Unknown message:",response); return -1; }
int main(void) { struct sockaddr_in clnt_addr; socklen_t addrlen = sizeof(clnt_addr); int ret; char buf[MSGLEN]; unsigned int time_left; int sock_fd = setup(); signal(SIGALRM, ticket_reclaim); alarm(RECLAIM_INTERVAL); while (true) { ret = recvfrom(sock_fd, buf, MSGLEN, 0, (struct sockaddr *)&clnt_addr, &addrlen); if (ret != -1) { buf[ret] = '\0'; narrate("GOT:", buf, &clnt_addr); time_left = alarm(0); handle_request(buf, &clnt_addr, addrlen); alarm(time_left); } else { if (errno != EINTR) perror("recvfrom"); } } return EXIT_SUCCESS; }
int main(int ac, char *av[]) { struct sockaddr_in client_addr; socklen_t addrlen; char buf[MSGLEN]; int ret; int sock; unsigned time_left; void ticket_reclaim(); sock = setup(); signal(SIGALRM, ticket_reclaim); alarm(RECLAIM_INTERVAL); while (1) { addrlen = sizeof(client_addr); ret = recvfrom(sock, buf, MSGLEN, 0, (struct sockaddr *)&client_addr, &addrlen); if (ret != -1) { buf[ret] = '\0'; narrate("GOT:", buf, &client_addr); time_left = alarm(0); handle_request(buf, &client_addr, addrlen); alarm(time_left); } else if (errno != EINTR) perror("recvfrom"); } }
/**************************************************************************** * * do_hello * * Give out a ticket if any are available * * IN msg_p message received from client * * Results: ptr to response * * NOTE: return is in static buffer overwritten by each call * */ static char *do_hello(char *msg_p) { int x; static char replybuf[MSGLEN]; if(num_tickets_out >= MAXUSERS) return("FAIL no tickets available"); /* else find a free ticket and give it to client */ for(x = 0; x<MAXUSERS && ticket_array[x] != TICKET_AVAIL; x++) ; /* A sanity check - should never happen */ if(x == MAXUSERS) { narrate("database corrupt","",NULL); return("FAIL database corrupt"); } /* Found a free ticket. Record "name" of user (pid) in array. * * generate ticket of form: pid.slot * */ ticket_array[x] = atoi(msg_p + 5); /* get pid in msg */ sprintf(replybuf, "TICK %d.%d", ticket_array[x], x); num_tickets_out++; return(replybuf); } /* do_hello */
char *do_goodbye(char *msg){ int pid, slot; if((sscanf((msg+5), "%d. %d", &pid, &slot) != 2) || (ticket_array[slot] != pid)){ narrate("Bogus ticket", msg+5, NULL); return "FAIL invalid ticket"; } ticket_array[slot] = TICKET_AVAIL; num_tickets_out--; return "THAX See ya!"; }
/**************************************************************************** * * do_validate * * Validate client's ticket * * IN msg_p message received from client * * Results: ptr to response * */ static char *do_validate(char *msg) { int pid, slot; /* components of ticket */ /* msg looks like VAD pid.slot - parse it and validate */ if (sscanf(msg+5,"%d.%d",&pid,&slot)==2 && ticket_array[slot] == pid) return("GOOD Valid ticket"); /* bad ticket */ narrate("Bogus ticket", msg+5, NULL); return("FAIL invalid ticket"); }
/******************************************************************* * do_validate * Validate client's ticket * IN msg_p message from client * Result: ptr to response * NOTE: return is in staitc buffer over written by each call */ static char *do_validate(char *msg) { int pid,slot; // components of ticket // message looks like VALD pid.slot if(sscanf(msg + 5,"%d.%d",&pid,&slot) == 2 && ticket_array[slot] == pid) return "GOOD Valid ticket"; // bad ticket narrate("Bogus ticket",msg + 5,NULL); return "FAIL invalid ticket"; }
void ticket_reclaim(){ int i; char tick[BUFSIZ]; for(i=0; i<MAXUSERS; i++){ if((ticket_array[i] != TICKET_AVAIL) && (kill(ticket_array[i], 0) == -1) && (errno == ESRCH)){ sprintf(tick, "%d. %d", ticket_array[i], i); narrate("freeing", tick, NULL); ticket_array[i] = TICKET_AVAIL; num_ticket_out--; } } alarm(RECLAIM_INTERVAL); }
handle_request(char *req, struct sockaddr_in *client, socklen_t addlen){ fprintf(stderr, "In handle_request\n"); fflush(stderr); char *response; int ret; if(strncmp(req, "HELO", 4) == 0) response = do_hello(req); else if(strncmp(req, "GBYE", 4) == 0) response = do_goodbye(req); else response = "FAIL invalid request"; narrate("SAID:", response, client); ret = sendto(sd, response, strlen(response), 0, client, addlen); if(ret == -1) perror("SERVER sendto failed"); }
/**************************************************************************** * * ticket_reclaim * * go through all tickets and reclaim ones belonging to dead processes * * Results: none * */ void ticket_reclaim() { int i; char tick[BUFSIZ]; for(i = 0; i < MAXUSERS; i++) { if((ticket_array[i] != TICKET_AVAIL) && (kill(ticket_array[i], 0) == -1) && (errno == ESRCH)) { /* Process is gone - free up slot */ sprintf(tick, "%d.%d", ticket_array[i],i); narrate("freeing", tick, NULL); ticket_array[i] = TICKET_AVAIL; num_tickets_out--; } } alarm(RECLAIM_INTERVAL); /* reset alarm clock */ }
/* handle_request(request, clientaddr, addrlen) * branch on code in request */ handle_request(char *req, struct sockaddr_in *client, socklen_t addlen) { char *response; int ret; /* act and compose a response */ if (strncmp(req, "HELO", 4) == 0) response = do_hello(req); else if(strncmp(req, "GBYE", 4) == 0) response = do_goodbye(req); else response = "FAIL invalid request"; /* send the response to the client */ narrate("SAID:", response, client); ret = sendto(sd, response, strlen(response), 0, client, addlen); if (ret == -1) perror("SERVER sendto failed"); }
/******************************************************************* * ticket_reclaim * go through all tickets and reclaim ones belonging to dead processes * Result: none */ void ticket_reclaim() { int i; char tick[BUFSIZ]; for(i = 0; i < MAXUSERS; ++i) { if(ticket_array[i] != TICKET_AVAIL && (kill(ticket_array[i],0) == -1) && errno == ESRCH) { // Proccess is gone - free up slot sprintf(tick,"%d.%d",ticket_array[i],i); narrate("freeing",tick,NULL); ticket_array[i] = TICKET_AVAIL; --num_tickets_out; } } alarm(RECLAIM_INTERVAL); // reset alarm clock } // ticket_reclaim
char *do_hello(char *msg){ fprintf(stderr, "In do_hello\n"); fflush(stderr); int x; static char replybuf[MSGLEN]; if(num_tickets_out >= MAXUSERS) return "FAIL no tickets available"; fprintf(stderr, "before search\n"); fflush(stderr); for(x=0; x<MAXUSERS && ticket_array[x]!=TICKET_AVAIL; x++); if(x == MAXUSERS){ narrate("db corrupt", "", NULL); return "FAIL db corrupt"; } fprintf(stderr, "befor atoi\n"); fflush(stderr); ticket_array[x] = atoi(msg+5); sprintf(replybuf, "TICK %d. %d", ticket_array[x], x); num_tickets_out++; return replybuf; }
/* take back ticket client is returning * IN msg_p message received from client * results: ptr to response * note: return is in static buffer overwritten by each call */ char *do_goodbye(char *msg_p) { int pid, slot; /* components of ticket */ /* the user's giving us back a ticket. first we need to * get the ticket out of the message, which looks like: * * GBYE pid.slot * */ if ((sscanf((msg_p + 5), "%d.%d", &pid, &slot) != 2) || (ticket_array[slot] != pid)) { narrate("bogus ticket", msg_p+5, NULL); return("FAIL invalid ticket"); } /* the ticket is valid. release it. */ ticket_array[slot] = TICKET_AVAIL; num_tickets_out--; return("THNX see ya!"); }
/******************************************************************* * do_goodbye * Tack back ticket client is returning * IN msg_p message received from client * Result: ptr to response * Note: retur is in static buffer over written by each call */ char * do_goodbye(char *msg_p) { int pid,slot; // componse of ticket /* The user's giving us back a ticket. First we need to get * the ticket out of the message, which look like: * GBYE pid.slot */ if((sscanf((msg_p + 5),"%d.%d",&pid,&slot) != 2) || (ticket_array[slot] != pid)) { narrate("Bogus ticket",msg_p + 5,NULL); return "FAIL invalid ticket"; } // The tickets si valid. Release it ticket_array[slot] = TICKET_AVAIL; --num_tickets_out; // return response return "THNX See ya!"; } // do_goodbye