home *** CD-ROM | disk | FTP | other *** search
- /* pscope (periscope) allows a macintosh connected to the network to
- "see" into a unix directory and retrieve files from it */
-
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <stdio.h>
- #include <errno.h>
- #include <sys/stat.h>
- #include <pwd.h>
-
- #define TRUE 1
- #define SEND 0
- #define RECEIVE 1
- #define MORE 0
- #define DONE 1
- #define kTCPBlockSize 256
- #define HANDSHAKE 2
- #define PROTOCOL_ERR 2
- #define TERMINATING 3
- #define BAD_NAME 4
-
- int inDescriptor;
- struct stat inStat;
- int inSize;
- FILE *in = stdin,*out = stdout;
- unsigned char *outbuf = NULL; /* file buffer -> mac */
-
- void handshake(buf,bytes,sock)
- char *buf;
- int bytes;
- int sock;
- {
- char *username;
- struct passwd *userinfo;
-
- unsigned char controlByte = buf[0];
-
- outbuf = (unsigned char *)malloc(1);
-
- if(controlByte != HANDSHAKE){
- /* protocol error */
- outbuf[0] = PROTOCOL_ERR;
- #ifdef DEBUG
- fprintf(stderr,"Bad Handshake\n");
- #endif
- if(write(sock,outbuf,1) < 0)
- perror("ERROR writing to socket");
- outbuf[0] = TERMINATING;
- if(write(sock,outbuf,1) < 0)
- perror("ERROR writing to socket");
- close(sock);
- exit(0);
- }
-
- /* rest of message is userid */
- username = (char *)malloc(bytes);
- memcpy(username,&buf[1],bytes-1);
- username[bytes-1] = '\0';
- userinfo = getpwuid(getuid());
- if(strcmp(username,userinfo->pw_name)){
- /* account names don't match */
- outbuf[0] = BAD_NAME;
- #ifdef DEBUG
- fprintf(stderr,"Bad Account\n");
- #endif
- if(write(sock,outbuf,1) < 0)
- perror("ERROR writing to socket");
- outbuf[0] = TERMINATING;
- if(write(sock,outbuf,1) < 0)
- perror("ERROR writing to socket");
- close(sock);
- free(userinfo);
- exit(0);
- }
-
- /* Don't worry, be happy! */
- free(userinfo);
- outbuf[0] = 0;
- if(write(sock,outbuf,1) < 0)
- perror("ERROR writing to socket");
- return;
- }
-
- void handleMessage(buf,size,msgsock)
- char *buf;
- int size;
- int msgsock;
- {
- unsigned char controlByte;
- int nBytes;
- char *data;
- char *filename;
- int bytesSent = 0;
- int bytesToGo;
- int sendBytes;
- controlByte = buf[0];
-
- switch(controlByte){
- case SEND:
- /* client wants server to send data, resulting from last request */
-
- /* allocate enough buffer space to transmit at least an error */
- outbuf = (unsigned char *)malloc(1);
-
- memcpy(&nBytes,&(buf[1]),sizeof(int)); /* no of bytes in file name */
- filename = (char *)malloc(nBytes+1);
- memcpy(filename,&(buf[5]),nBytes); /* got the filename assigned */
- filename[nBytes] = '\0'; /* termninate fname string */
-
- /* set error flag */
- outbuf[0] = 1;
-
- if((inDescriptor = open(filename,0)) == -1){
- #ifdef DEBUG
- fprintf(stderr,"failed to open %s\n",filename);
- #endif
- if(write(msgsock,outbuf,1) < 0)
- perror("ERROR writing to socket");
- break;
- }
- free(filename);
- /* get input file info */
-
- fstat(inDescriptor,&inStat);
- inSize = inStat.st_size;
-
- /* dynamically allocate enough buffer space here */
- outbuf = (unsigned char *)realloc(outbuf,inSize+4+1);
- /* write number of bytes in data to buffer */
- memcpy(&outbuf[1],&inSize,sizeof(inSize));
-
- nBytes = read(inDescriptor,&(outbuf[5]),inSize);
-
- #ifdef DEBUG
- fprintf(stderr,"read %d bytes\n",nBytes);
- #endif
-
- if(nBytes < 0){
- #ifdef DEBUG
- fprintf(stderr,"read error: %d\n",errno);
- #endif
- if(write(msgsock,outbuf,1) < 0)
- perror("ERROR writing to socket");
- break;
- }
- else if (nBytes == 0){
- #ifdef DEBUG
- fprintf(stderr,"No data read\n");
- #endif
- if(write(msgsock,outbuf,1) < 0)
- perror("ERROR writing to socket");
- break;
- }
-
- outbuf[0] = 0; /* data is good */
- /* send control byte + size int */
- if(write(msgsock,outbuf,5) < 0)
- perror("ERROR writing to socket");
- if(write(msgsock,&(outbuf[5]),inSize) < 0)
- perror("ERROR writing to socket");
-
- break;
-
- case RECEIVE:
- /* client wants to send data to the server */
- memcpy(&nBytes,&(buf[1]),sizeof(int));
- fprintf(stderr,"RECEIVE\n");
- fflush(stderr);
- ntohs(nBytes);
- fprintf(stderr,"nBytes = %d\n",nBytes);
- fprintf(stderr,"%d\n%d\n%d\n%d\n",buf[1],buf[2],buf[3],buf[4]);
- data = (char *)malloc((nBytes + 1) * sizeof(char));
- memcpy(data,&(buf[1+sizeof(int)]),nBytes);
- data[nBytes] = '\0';
- fprintf(out,"-->%s\n",data);
- free(data);
- break;
-
- default:
- break;
- }
- }
-
- main(argc,argv)
- int argc;
- char **argv;
- {
-
- int port = 32200;
- int sock , range = 10, length;
- struct sockaddr_in server;
- int msgsock;
- char buf[1024];
- int rval;
- fd_set ready;
- struct timeval to;
- char *filename;
- extern char *optarg;
- int nonOptArgs;
- char c;
- int p_flag = 0;
- int r_flag = 0;
- int done = 0;
- int result;
-
- /* process command line args */
- while((c = getopt(argc,argv,"p:r:")) != -1)
- switch(c){
- case 'p':
- p_flag = 1;
- port = atoi(optarg);
- break;
- case 'r':
- r_flag = 1;
- range = atoi(optarg);
- break;
- default:
- #ifdef DEBUG
- fprintf("improper option ignored\n");
- #endif
- ;
- }
-
- nonOptArgs = argc - 1 - p_flag - r_flag;
-
- /* Create Socket */
-
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock < 0)
- {
- perror("ERROR opening stream socket");
- exit(1);
- }
-
- /* Name socket using wilddcards */
-
- server.sin_family = AF_INET;
- server.sin_addr.s_addr = INADDR_ANY;
- server.sin_port = port;
- /* search until unused port# is found or range exhausted */
- while(!done && server.sin_port < (port + range)){
- result = bind(sock, (struct sockaddr *)&server,
- sizeof server);
- if(result < 0)
- server.sin_port++;
- else
- done = 1;
- }
- if(!done){
- fprintf(stderr,"Unable to bind socket to port, exitting...\n");
- exit(1);
- }
- #ifdef DEBUG
- fprintf(stderr,"Socket prot #%d\n", ntohs(server.sin_port));
- #endif
-
- /* Start accepting connections */
-
- listen(sock, 5);
- do
- {
- FD_ZERO(&ready);
- FD_SET(sock, &ready);
- to.tv_sec = 5;
- if (select(sock + 1, &ready, (fd_set *)0,
- (fd_set *)0, &to) < 0)
- {
- perror("ERROR select");
- continue;
- }
- if (FD_ISSET(sock, &ready))
- {
- msgsock = accept(sock, (struct sockaddr *)0,
- (int *)0);
- if (msgsock == -1) perror("ERROR accept");
- else {
- if(fork() == 0){ /* child */
- close(sock);
-
- /* do the handshake */
- bzero(buf,sizeof buf);
- if ((rval = read(msgsock, buf, 1024)) < 0) {
- perror("ERROR reading stream message");
- close(msgsock);
- exit(0); /* child dies */
- }
- if(rval == 0){
- close(msgsock);
- exit(0);
- }
- handshake(buf,rval,msgsock);
-
- do
- {
- bzero(buf, sizeof buf);
- /* block until data is available */
- if ((rval = read(msgsock, buf, 1024)) < 0) {
- perror("ERROR reading stream message");
- close(msgsock);
- exit(0); /* child dies */
- }
- else if (rval == 0)
- printf("No more data\n");
- else
- handleMessage(buf,1024,msgsock);
- }
- while(rval > 0);
- }
- close(msgsock); /* parent */
- }
- }
- }
- while(TRUE);
- exit(0);
- }
-