/* TCPECHOS ---/--+----- IUCV -----+---+---- NONE ----+---+---------+-< | | | | | | '----- INET -----' +---- POSIX ---+ '--DEBUG--' | | '----- MT -----' To run: 1. GLOBAL LOADLIB SCEERUN 2. TCPECHOS .... To build: 1. GLOBAL TXTLIB SCEELKED CMSLIB 2. GLOBAL LOADLIB SCEERUN 3. c89 -W 0,SSCOMM //tcpecho.c -o //tcpecho -l //POSXSOCK -l //VMMTLIB */ /* #define _NO_PROTO */ #include "tcpecho.h" int exitflag = 0; static void* GetData( void *ns ) { int rc, nbytes, socksize, offset, rcvlen, total; union { struct sockaddr_iucv siucv; struct sockaddr_in sinet; } ClientSock; struct { char userid[8]; int seqno; char text[BUFFER_LEN]; } buffer; char sure[] = "guaranteed"; char unsure[] = "suspect"; char vmuserid[9]; char *who, *where, *seclevel; printf(" Receiving data on fd %d\n", ns); socksize = sizeof ClientSock; printf(" Getpeername\n"); getpeername(ns, (struct sockaddr *)&ClientSock, &socksize); printf(" Got peername\n"); if (ClientSock.siucv.siucv_family == AF_IUCV) { /* getpeeruserid(c, vmuserid); */ seclevel = sure; who = ClientSock.siucv.siucv_userid; where = "\0"; }else{ seclevel = unsure; who = buffer.userid; where = inet_ntoa( ClientSock.sinet.sin_addr ); } do { offset = total = 0; rcvlen = sizeof buffer; do { printf(" read(%d)\n", rcvlen); nbytes = read(ns, (char *)(&buffer+offset), rcvlen); if ((nbytes < rcvlen) && (nbytes > 0) ) { printf(" %d: From %.8s %s (%s): (partial data=%d)\n", ns, who, where, seclevel, nbytes); offset = offset + nbytes; rcvlen = rcvlen - nbytes; } if (nbytes > 0) total = total + nbytes; } while ( (nbytes > 0) && (total < sizeof buffer)); if (nbytes > 0) { printf(" %d: From %.8s %s (%s): %8d %s\n", ns, who, where, seclevel, buffer.seqno, buffer.text); if (strcmp(buffer.text, "*EXIT*") == 0) exitflag = 1; } } while (nbytes > 0); if (nbytes < 0) { printf("read() for fd %d failed", ns); perror("read()"); } rc = close(ns); if (rc < 0) { printf("close() for fd %d failed", ns); perror("close()"); } if (nbytes == 0) printf(" All data received on fd %d\n", ns); return NULL; } /*****************************************************************/ /*****************************************************************/ /** **/ /** M A I N **/ /** **/ /*****************************************************************/ /*****************************************************************/ int main ( int argc, char *argv[]) { enum thread_values {NONE, MT, POSIX} thread_type = NONE; pthread_t ptid; int s, ns, rc, re, tid, socktype = AF_IUCV, socksize; int dbg = 0; union { struct sockaddr_iucv siucv; struct sockaddr_in sinet; } mySock; printf("ARGC = %d\n", argc); if (argc > 1 && strcmp(argv[1], "INET") == 0) socktype = AF_INET; if (argc > 1 && strcmp(argv[1], "IUCV") == 0) socktype = AF_IUCV; if (argc > 2 && strcmp(argv[2], "POSIX") == 0) thread_type = POSIX; if (argc > 2 && strcmp(argv[2], "MT") == 0) thread_type = MT; if (argc = 4 && strcmp(argv[3], "DEBUG") == 0) dbg = 1; s = socket(socktype, SOCK_STREAM, 0); exit_if_error(Socket, s); Clear(mySock); switch (socktype) { case AF_IUCV: printf("Using domain AF_IUCV\n"); socksize = sizeof mySock.siucv; mySock.siucv.siucv_family = AF_IUCV; memcpy( mySock.siucv.siucv_name, SERVER, 8); memset( mySock.siucv.siucv_nodeid, ' ', 8); break; case AF_INET: printf("Using domain AF_INET\n"); socksize = sizeof mySock.sinet; mySock.sinet.sin_family = AF_INET; mySock.sinet.sin_addr.s_addr = INADDR_ANY; mySock.sinet.sin_port = SERVER_PORT; break; default: break; } if (dbg) printf("Binding...\n"); rc = bind(s, (struct sockaddr *)&mySock, socksize); if (dbg) printf("Bind RC=%d\n",rc); exit_if_error(bind, rc); if (dbg) printf("Listening...\n"); rc = listen(s, 0); if (dbg) printf("Listen RC=%d\n", rc); exit_if_error(listen, rc); while (!exitflag) { if (dbg) printf("Main(): Accept(%d,0,0) waiting...\n", s); ns = accept(s, 0, 0); exit_if_error(accept, ns); switch ( thread_type ) { case MT: printf("Main(): Using ThreadCreate for fd %d\n", ns); ThreadCreate(&rc,&re, &tid, &rc, 0, 0, (int)&GetData, (void *)ns, 1); exit_if_error(ThreadCreate, rc); break; case POSIX: printf("Main(): Using pthread_create for fd %d\n", ns); rc = pthread_create(&ptid, NULL, GetData, (void *)ns); exit_if_error(pthread_create, rc); break; default: printf("Using standard call for fd %d\n", ns); GetData( (void *)ns ); } } rc = close(s); exit_if_error(mainclose, rc); return(0); }