/* $Header: /users/server/students/cs522/project/sharedraw/RCS/ua.c,v 1.3 1992/11/02 18:59:27 chow Exp $ */ /* sender for internet datagram demo */ /* with select and time-out */ #include #include #include #include #include #include #include #include "msg.h" #include "Servermsg.h" #define ENDPACKET "end" printmsg(msg, cc) char *msg; int cc; { int i; printf("Got Message:%s\n", msg); for (i= 0; i <#timeout.usec> hostname portno\n"); printf(" option: d set debug mode\n"); } main(argc, argv) int argc; char *argv[]; { /*create socket*/ int sockTo; int sockFrom; int sockToGui; int sockFromGui; int sockToRUA; struct sockaddr_in to; struct sockaddr_in toRUA; int connected; struct sockaddr_in from; struct hostent *hp, *gethostbyname(); struct sockaddr_un name; struct sockaddr_un toGuiName; /*transfer message struct*/ union Record r; union Message msg; /*select varables*/ int maxfdpl; struct timeval timeout; fd_set fdvar; long atol(); int setTimeOut = 0; /* flag for setting timeout, */ int counter = 0; int n; int i; int pcount = 0; /* count of packets sent */ int quitFlag = 1; char toGuiSocketName[40]; char fromGuiSocketName[40]; char hostname[64]; extern char *optarg; extern int optind; int option_exist = 0; int c; int debug = 0; char *rcv_name; /* receiver's socket name */ int toPort_no; char *username; /*input user name*/ int length; int flag; extern char* getlogin(); char* login = getlogin(); /* process command line args */ while ((c=getopt(argc,argv,"d")) != EOF) { option_exist = 1; switch(c) { case 'd': debug = 1; if (debug) printf("turn on debug mode.\n"); break; case '?': help_msg(); exit (1); default: fprintf (stderr, "unrecognized arg >%s<\n", optarg); help_msg(); exit (1); } } if (argc < 5) { help_msg(); exit (1); } /* create a unix domain socket to relay msg to Gui */ sockToGui = initSockToGui(); /* create name structure for the UNIX domain socket */ toGuiName.sun_family = AF_UNIX; sprintf(toGuiSocketName, "/tmp/cs522.%s.UA2Gui", login); strcpy(toGuiName.sun_path, toGuiSocketName); printf("socket to gui-->%s\n", toGuiSocketName); /* create a unix domain socket from which to read */ sockFromGui = socket(AF_UNIX, SOCK_DGRAM, 0); if (sockFromGui < 0) { perror("opening datagram socket"); exit(1); } name.sun_family = AF_UNIX; sprintf(fromGuiSocketName, "/tmp/cs522.%s.Gui2UA", login); strcpy(name.sun_path, fromGuiSocketName); if (bind(sockFromGui, &name, sizeof(struct sockaddr_un))) { perror("binding name to datagram socket"); exit(1); } /*get input arguments*/ username= argv[optind++]; timeout.tv_sec = atol(argv[optind++]); timeout.tv_usec = atol(argv[optind++]); rcv_name = argv[optind++]; if ((toPort_no = atoi(argv[optind])) < 1025) toPort_no = 1025; /* create socket from which to read */ sockFrom = socket(AF_INET, SOCK_DGRAM, 0); if (sockFrom < 0) { perror("opening datagram socket"); exit(1); } /* create name structure with wildcard using INADDR_ANY */ from.sin_family = AF_INET; from.sin_addr.s_addr = INADDR_ANY; from.sin_port = 0; /*bind socket from to read*/ if (bind(sockFrom, &from, sizeof(struct sockaddr_in))) { perror("binding name to datagram socket"); exit(1); } length = sizeof(from); if (getsockname(sockFrom, &from, &length)) { perror("getting socket name"); exit(1); } /* Find assigned port value and print out. */ printf("socket has port #%d\n", ntohs(from.sin_port)); /* create socket on which to sent */ sockTo = socket(AF_INET, SOCK_DGRAM, 0); if (sockTo < 0) { perror("opening datagram socket"); exit(1); } to.sin_family = AF_INET; to.sin_addr.s_addr = INADDR_ANY; to.sin_port = 0; if (bind(sockTo, &to, sizeof(to))) { perror("binding datagram socket"); exit(1); } /*assign the sedning socket addres*/ hp = gethostbyname(rcv_name); if (hp == 0) { fprintf(stderr, "%s: unknown host",rcv_name); exit(2); } bcopy(hp->h_addr, &to.sin_addr, hp->h_length); to.sin_family = AF_INET; to.sin_port = htons(toPort_no); /*send message to server to regist the user */ gethostname(hostname, 64); printf("hostname=%s\n", hostname); printf("sending registration message: %s %d %s\n", hostname, ntohs(from.sin_port), login); /*form the regist message*/ msg.regist.msgType=REG; strcpy(msg.regist.username,username); strcpy(msg.regist.userLogin,login); strcpy(msg.regist.hostname,hostname); msg.regist.portId=ntohs(from.sin_port); if (sendto(sockTo, &(msg.regist.msgType), sizeof(msg), 0, &to, sizeof(to)) < 0) perror("sending datagram message"); /* create socket on which to sent data to remote user agent */ sockToRUA = socket(AF_INET, SOCK_DGRAM, 0); if (sockToRUA < 0) { perror("opening datagram socket"); exit(1); } toRUA.sin_family = AF_INET; toRUA.sin_addr.s_addr = INADDR_ANY; toRUA.sin_port = 0; if (bind(sockToRUA, &toRUA, sizeof(toRUA))) { perror("binding datagram socket"); exit(1); } maxfdpl = (sockFrom > sockFromGui) ? sockFrom+1 : sockFromGui+1; printf("maxfdpl=%d\n", maxfdpl); /*this while loop receives message from Gui and the other user, and response to send back acording message*/ while (quitFlag) { FD_ZERO(&fdvar); /* initialize the set -- all bits off */ FD_SET(sockFrom, &fdvar); /* turn on bit for fd sockFrom */ FD_SET(sockFromGui, &fdvar); /* turn on bit for fd sockFromGui */ if (setTimeOut) { if ((i=select(maxfdpl, &fdvar, (fd_set *) 0, (fd_set *) 0, &timeout)) < 0) perror("select error"); if (i == 0) { printf("Time out! The receiver does not respond.\n"); exit(1); } } else { /* wait indefinitely, no timeout */ if ((i=select(maxfdpl, &fdvar, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0)) < 0) perror("select error"); } /*message comes from Gui*/ if (FD_ISSET(sockFromGui, &fdvar)) { bzero(&(r.pr.msgType), sizeof(r)); n = recv(sockFromGui, &(r.pr.msgType), sizeof(r), 0); if (n < 0) perror("receiving datagram message"); printf("message from Gui,type=%d\n",r.pr.msgType); /*response for different message*/ switch (r.pr.msgType) { /*PEN message*/ case PEN: /* relay the message to the connected user */ /* not connected */ if (connected == 0) break; /*if (r.pr.msgType == DISC) connected = 0;*/ if (sendto(sockToRUA, &(r.pr.msgType), n, 0, &toRUA, sizeof(toRUA)) < 0) perror("sending datagram message"); break; /*ERASER message*/ case ERASER: /* relay the message to the connected user */ if (connected == 0) break; /* not connected */ /*if (r.pr.msgType == DISC) connected = 0;*/ if (sendto(sockToRUA, &(r.er.msgType), n, 0, &toRUA, sizeof(toRUA)) < 0) perror("sending datagram message"); break; /*CURSOR msg*/ case CURSOR: /* relay the message to the connected user */ if (connected == 0) break; /* not connected */ /*if (r.pr.msgType == DISC) connected = 0;*/ if (sendto(sockToRUA, &(r.cr.msgType), n, 0, &toRUA, sizeof(toRUA)) < 0) perror("sending datagram message"); break; /*TEXT msg*/ case TEXT: /* relay the message to the connected user */ if (connected == 0) break; /* not connected */ /*if (r.pr.msgType == DISC) connected = 0;*/ if (sendto(sockToRUA, &(r.tr.msgType), n, 0, &toRUA, sizeof(toRUA)) < 0) perror("sending datagram message"); break; /*CLEAN msg*/ case CLEAN: /* relay the message to the connected user */ if (connected == 0) break; /* not connected */ /*if (r.pr.msgType == DISC) connected = 0;*/ if (sendto(sockToRUA, &(r.clr.msgType), n, 0, &toRUA, sizeof(toRUA)) < 0) perror("sending datagram message"); break; case DISC: case BOB: case NOB: /* relay the message to the connected user */ if (connected == 0) break; /* not connected */ if (r.pr.msgType == DISC) connected = 0; if (sendto(sockToRUA, &(r.pr.msgType), n, 0, &toRUA, sizeof(toRUA)) < 0) perror("sending datagram message"); break; case QUIT: printf("The user is exiting.\n"); quitFlag = 0; break; case CONN: /* get the conn msg, forward it to IS */ msg.conn.msgType=CONN; strcpy(msg.conn.fromUsername,username); strcpy(msg.conn.toUsername,r.nr.name); if (sendto(sockTo, &(msg.conn.msgType), sizeof(msg), 0, &to, sizeof(to)) < 0) perror("sending datagram message right here"); break; case ACK: msg.cack.msgType=ACK; strcpy(msg.cack.fromUsername,username); strcpy(msg.cack.toUsername,r.ackr.originator); if (sendto(sockTo, &(msg.cack.msgType), sizeof(msg), 0, &to, sizeof(to)) < 0) perror("sending datagram message right here"); break; case NAK: /* user rejects the connection request */ /* send response back to IS */ msg.cack.msgType=NAK; strcpy(msg.nak.fromUsername,username); strcpy(msg.nak.toUsername,r.nakr.originator); if (sendto(sockTo, &(msg.nak.msgType), sizeof(msg), 0, &to, sizeof(to)) < 0) perror("sending datagram message right here"); break; default: printf("undefined msg type.-------\n"); break; } } /*message from other user*/ if (FD_ISSET(sockFrom, &fdvar)) { bzero(&(msg.regist.msgType), sizeof(msg)); n = recv(sockFrom, &(msg.regist.msgType), sizeof(msg), 0); if (n < 0) perror("receiving datagram message RIGHT HERE!!!"); setTimeOut = 0; /*response different type of message*/ switch (msg.regist.msgType) { case ACK: printf("connection established====\n"); printf("des host=%s\n",msg.cack.hostname); connected = 1; hp = gethostbyname(msg.cack.hostname); if (hp == 0) { fprintf(stderr, "%s: unknown host",rcv_name); exit(2); } bcopy(hp->h_addr, &toRUA.sin_addr, hp->h_length); toRUA.sin_family = AF_INET; toRUA.sin_port = htons(msg.cack.portId); r.ackr.msgType=ACK; strcpy(r.ackr.userLogin,msg.cack.fromUsername); if (sendto(sockToGui, &(r.ackr.msgType), n, 0, &toGuiName, sizeof(toGuiName)) < 0) perror("sending datagram message"); break; case NAK: /* relay the NAK message to GUI */ printf("get NAK message.the reason is %s\n",msg.nak.reason); r.nakr.msgType=NAK; strcpy( r.nakr.reason,msg.nak.reason); if (sendto(sockToGui, &(r.nakr.msgType), n, 0, &toGuiName, sizeof(toGuiName)) < 0) perror("sending datagram message"); break; case PEN: case ERASER: case CURSOR: case TEXT: case CLEAN: case DISC: case BOB: case NOB: /* relay the message from RUA to the GUI */ if (connected == 0) break; /* not connected */ if (msg.regist.msgType == DISC) connected = 0; if (sendto(sockToGui, &(msg.pen.msgType), n, 0, &toGuiName, sizeof(toGuiName)) < 0) perror("sending datagram message"); break; case CONN: /* request from IS for permission to connect */ r.nr.msgType=CONN; strcpy(r.nr.originator,msg.conn.fromUsername); if (sendto(sockToGui, &(r.nr.msgType),sizeof(r), 0, &toGuiName, sizeof(toGuiName)) < 0) perror("sending datagram message"); printf("received conn request\n"); break; case RACK: printf("type=%d\n",msg.rack.msgType); printf("from=%s\n",msg.rack.fromUsername); printf("to=%s\n",msg.rack.toUsername); break; default: printf("undefined msg type.\n"); break; } } } close(sockToGui); close(sockFromGui); close(sockFrom); close(sockTo); close(sockToRUA); }