/* * $Id: tsosubd.c,v 1.1.1.1 1996/03/08 15:44:22 mclareni Exp $ * * $Log: tsosubd.c,v $ * Revision 1.1.1.1 1996/03/08 15:44:22 mclareni * Cspack * */ #if defined(CERNLIB_IBMMVS) #include "sys/CERNLIB_machine.h" #include "_cspack/pilot.h" /* TSOSUBD Version 1.1.4 - 19 Feb 1990 */ #define MVS #include #include #include #include #include #include #include #include #pragma linkage(CMXLATE,OS) #define JCL_OUTPUT_DSN "TSOSUB.CNTL" #define FALSE (0) #define TRUE (1) #define PORTMIN 5001 /* Portnumbers start at PORTMIN+1 */ #define PORTMAX 5500 #define BACKLOG 5 #define MAXHOSTNAME 32 #define recv_submit_send RESUWR #define VERSION "1.0.0 1/1/92" int verbose; int sport = PORTMIN; int jobnumber = -1; main(argc,argv) int argc; char **argv; { int listen_socket, jcl_socket; int i; int port_number; struct linger l; struct sockaddr_in sa; struct sockaddr_in r_sa; int r_sa_lng; char *inet_ntoa(); char remote_host[150]; struct sockaddr isa; struct hostent *hp; struct servent *sp; char localhost[MAXHOSTNAME+1]; int wake_up_interval; int num_fds, nfound; unsigned long readfds; struct timeval timeout; time_t lt; int i_reuseaddr; port_number = 5001; verbose = FALSE; wake_up_interval = 0; for(i = 1; i < argc; ++i) { if(argv[i][0] != '-') continue; switch(argv[i][1]) { case 'w': case 'W': if(++i == argc) continue; wake_up_interval = atoi(argv[i]); break; case 'p': case 'P': if(++i == argc) continue; port_number = atoi(argv[i]); break; case 'v': case 'V': verbose = TRUE; break; } /* switch (argv..... */ } /* for(argn.... */ /* Get a socket */ if ((listen_socket = socket(AF_INET,SOCK_STREAM,0)) < 0) { tcperror("socket"); exit(1); } if (verbose) { printf("listen_socket = %i\n",listen_socket); } /* I want to reuse address */ i_reuseaddr = 1; if ( setsockopt( listen_socket, SOL_SOCKET, SO_REUSEADDR, (char *) &i_reuseaddr,sizeof(i_reuseaddr)) < 0 ) { tcperror("setsocketopt SO_REUSEADDR"); } /* Get the local host information */ (void)gethostname(localhost,MAXHOSTNAME); if((hp = gethostbyname(localhost)) == NULL) { fprintf(stderr,"Cannot get local host info?\n"); exit(1); } /* Set the things for the bind call */ sa.sin_addr.s_addr=INADDR_ANY; sa.sin_family = hp->h_addrtype; sa.sin_port=port_number; /* bind the socket */ if(bind(listen_socket,&sa,sizeof sa,0) < 0) { tcperror("bind"); exit(1); } listen(listen_socket,BACKLOG); /* print out a startup message */ printf("TSOSVR Version %s GSI / Darmatadt\n",VERSION); time(<); printf("Server started at %s\n",asctime(localtime(<))); /* Loop forever */ for (;;) { if (wake_up_interval != 0) { readfds |= (1 << listen_socket); timeout.tv_sec=wake_up_interval; nfound = select(listen_socket+1,&readfds,0,0,&timeout); if (nfound==0) { continue; } } /* wake_up_interval */ /* Just wait for someone to connect to us */ i = sizeof isa; if ((jcl_socket = accept(listen_socket,&isa,&i)) < 0) { tcperror("accept"); exit(1); } r_sa_lng = sizeof r_sa; if (getpeername(jcl_socket,&r_sa,&r_sa_lng) != 0) { tcperror("accept"); } strcpy(remote_host,inet_ntoa(r_sa.sin_addr.s_addr)); time(<); strcat(remote_host," on "); strcat(remote_host,asctime(localtime(<))); remote_host[strlen(remote_host)-1]='\0'; printf("\nConnection from %s.\n",remote_host); fflush(stdout); /* read and submit JCL */ if (read_submit(jcl_socket)) { /* readjcl will return 1 if special "stop-string" is received */ if ( close(listen_socket,2) < 0) { tcperror("close listen_socket"); } if ( close(jcl_socket,2) < 0) { tcperror("close jcl_socket"); } printf("Shutting down.\n"); fflush(stdout); fflush(stderr); exit(0); } /* all done close the jcl_socket, and go wait for the next connect */ if ( close(jcl_socket,2) < 0) { tcperror("close jcl_socket"); } if (verbose) { printf("jcl_socket is closed\n"); } fflush(stdout); fflush(stderr); } } int read_submit(sock) int sock; { char rmachine[80]; char ruser[80]; char rtty[80]; char mvs_userid[80]; char mvs_passwd[80]; char tso_cmd[80]; char cmvs_sport[80]; int mvs_sport; extern char asciitoebcdic[]; extern char ebcdictoascii[]; char cmd[80]; char command[80]; char jobname[80]; char servreply[80]; int i_open = 0; register char *c; FILE *jcl_output; int k; int j=0; int i; int ilines = 7; char *cntl??(??) = { "//TSO EXEC LGN001 \n", "//SYSIN DD DUMMY \n", "//SYSPRINT DD SYSOUT=T \n", "//SYSTERM DD SYSOUT=T \n", "//FT05F001 DD DUMMY \n", "//FT06F001 DD SYSOUT=T \n", "//SYSTSPRT DD SYSOUT=T \n", "//SYSTSIN DD * \n"}; if (verbose) { printf ("read_submit entered\n"); fflush(stdout); } /* read strings from socket */ if ( getstr(sock,rmachine,sizeof(rmachine),"rmachine") <= 0) { sprintf(servreply,"Error: Problem in getting rmachine"); goto bad; } if ( getstr(sock,ruser,sizeof(ruser),"ruser") <= 0) { sprintf(servreply,"Error: Problem in getting ruser"); goto bad; } if ( getstr(sock,rtty,sizeof(rtty),"rtty") <= 0) { sprintf(servreply,"Error: Problem in getting rtty"); goto bad; } if ( getstr(sock,mvs_userid,sizeof(mvs_userid),"mvs_userid") <= 0) { sprintf(servreply,"Error: Problem in getting mvs_userid"); goto bad; } if ( getstr(sock,mvs_passwd,sizeof(mvs_passwd),"mvs_passwd") <= 0) { sprintf(servreply,"Error: Problem in getting mvs_passwd"); goto bad; } if ( getstr(sock,tso_cmd,sizeof(tso_cmd),"tso_cmd") <= 0) { sprintf(servreply,"Error: Problem in getting tso_cmd"); goto bad; } if ( getstr(sock,cmvs_sport,sizeof(cmvs_sport),"cmvs_sport") <= 0) { sprintf(servreply,"Error: Problem in getting cmvs_sport"); goto bad; } CMXLATE(rmachine,asciitoebcdic,strlen(rmachine)); CMXLATE(ruser,asciitoebcdic,strlen(ruser)); CMXLATE(rtty,asciitoebcdic,strlen(rtty)); CMXLATE(mvs_userid,asciitoebcdic,strlen(mvs_userid)); CMXLATE(mvs_passwd,asciitoebcdic,strlen(mvs_passwd)); CMXLATE(tso_cmd,asciitoebcdic,strlen(tso_cmd)); CMXLATE(cmvs_sport,asciitoebcdic,strlen(cmvs_sport)); c = mvs_passwd; while (*c) { if (islower(*c)) *c = toupper(*c); c++; } c = mvs_userid; while (*c) { if (islower(*c)) *c = toupper(*c); c++; } mvs_sport = atoi(cmvs_sport); if (verbose) { printf ("We have read from socket\n"); printf ("rmachine : %s \n",rmachine); printf ("ruser : %s \n",ruser); printf ("rtty : %s \n",rtty); printf ("mvs_userid : %sē\n",mvs_userid); printf ("tso_cmd : %s \n",tso_cmd); printf ("mvs_sport : %i \n",mvs_sport); fflush(stdout); } /* test of mvs_userid/mvs_passwd */ if (chpass(mvs_userid,mvs_passwd) <0 ){ sprintf(servreply, "Bad user and/or password for user %s.",mvs_userid) ; goto bad; } /* shutting down */ if ((!strncmp(mvs_userid,"RZ",2) || !strncmp(mvs_userid,"RS",2)) && !strncmp(tso_cmd,"tsosubend",9) ) { sprintf(servreply,"Shutting down TSOSUB."); j = 1; goto bad; } /* add sport to tso command, if sport == 0 */ if (mvs_sport == 0 ) { if( ++sport >= PORTMAX ) sport = PORTMIN; sprintf(command,"%s %d",tso_cmd,sport); sprintf(cmvs_sport,"%i",sport); } else { strcpy(command,tso_cmd); } if (verbose) { printf(" command = %s\n",command); } /* open jcl_output_dsn */ if ((jcl_output=fopen(JCL_OUTPUT_DSN, "w,blksize=3120,lrecl=80,recfm=fb")) == NULL) { sprintf(servreply, "Error: MVS-Server: Could not open %s (help data-set on MVS)", JCL_OUTPUT_DSN); goto bad; } i_open = 1; /* add job card */ if( ++jobnumber >= 100 ) jobnumber = 0; sprintf(jobname,"%sTS%02i",mvs_userid,jobnumber); fprintf(jcl_output, "//%s JOB CLASS=B,MSGCLASS=T,REGION=7000K,\n",jobname); fprintf(jcl_output, "// USER=%s,PASSWORD=%s\n",mvs_userid,mvs_passwd); /* write to jcl_output_dsn */ for ( i = 0 ; i <= ilines ; i++ ) { fprintf(jcl_output,"%s",cntl??(i??)); } /* add command */ if (!fprintf(jcl_output,"%s\n",command)) { sprintf(servreply, "Error: MVS-Server: TSO-Command could not be added to CNTL"); goto bad; } i_open = 0; /* close jcl_output_dsn */ if (( fclose(jcl_output)) != 0 ) { sprintf(servreply, "Error: MVS-Server: Could not close %s (help data-set on MVS)", JCL_OUTPUT_DSN); goto bad; } /* submit jcl_output_dsn */ sprintf(cmd,"submit %s ",JCL_OUTPUT_DSN); if (system(cmd) != 0) { sprintf(servreply, "Error: MVS-Server: System call (submit) ended with an error"); goto bad; } sprintf(servreply,"Job %s submitted on MVS",jobname); bad: /* close jcl_output_dsn */ if (i_open) { if (( fclose(jcl_output)) != 0 ) { fprintf(stderr, "Error: MVS-Server: Could not close %s (help data-set on MVS)" , JCL_OUTPUT_DSN); } } if (verbose) { printf("servreply =%s\n",servreply); } CMXLATE(cmvs_sport,ebcdictoascii,strlen(cmvs_sport)); CMXLATE(servreply,ebcdictoascii,strlen(servreply)); /* send client sport,servreply */ if ( send(sock, cmvs_sport, strlen(cmvs_sport) + 1, 0) < 0) { tcperror("Send sport "); exit(1); } if ( send(sock, servreply, strlen(servreply) + 1, 0) < 0) { tcperror("Send servreply "); exit(1); } return(j); } /* This routines are copied from tcpaw to tsosubd. * They are : getstr chpass chpas reply */ /* * read a string from the socket (sock). * * Returns: Number of bytes in the string * -1 for an error */ getstr(sock,buf, cnt, errmesg) int *sock; char *buf; int cnt; /* sizeof() the char array */ char *errmesg; /* in case error message required */ { char c; int k = 0; do { if ( read(sock, &c, 1) != 1) { printf("Error or EOF while reading %s from socket.\n", errmesg); return(-1); /* error or EOF */ } *buf++ = c; k++; if (--cnt == 0) { printf("%s too long from socket.\n", errmesg); return(-1); } } while (c!= 0); /* null byte terminates the string */ return(k-1); } int chpass(user, pass) /* For IBM */ char *user, *pass; { char *topoint; int i; topoint = user; while (*topoint != '\0'){ toupper(*topoint); topoint++; } topoint = pass; while (*topoint != '\0'){ toupper(*topoint); topoint++; } if (CHPAS(user,pass)){ /*if pw check no ok (done in assembler) */ reply("Bad user/password for %s.\n", user); return(-3); } reply("User %s accepted.\n", user); return(1); } int CHPAS(user, pass) /* For IBMMVS */ char *user, *pass; { int i; char cmd??(80??); i = sprintf(cmd,"TSOEXEC PWDCHK2 %s,%s",user,pass); i = system(cmd); /* i = 0 user,pass ok */ /* i = 4 user,pass not ok */ return(i); } reply(s1, s2, s3) char *s1, *s2, *s3; { printf(s1, s2, s3); fflush(stdout); } /* TSOSUBD Version 1.1.4 - 19 Feb 1990 */ #define MVS #include #include #include #include #include #include #include #include #pragma linkage(CMXLATE,OS) #define JCL_OUTPUT_DSN "TSOSUB.CNTL" #define FALSE (0) #define TRUE (1) #define PORTMIN 5001 /* Portnumbers start at PORTMIN+1 */ #define PORTMAX 5500 #define BACKLOG 5 #define MAXHOSTNAME 32 #define recv_submit_send RESUWR #define VERSION "1.0.0 1/1/92" int verbose; int sport = PORTMIN; int jobnumber = -1; main(argc,argv) int argc; char **argv; { int listen_socket, jcl_socket; int i; int port_number; struct linger l; struct sockaddr_in sa; struct sockaddr_in r_sa; int r_sa_lng; char *inet_ntoa(); char remote_host[150]; struct sockaddr isa; struct hostent *hp; struct servent *sp; char localhost[MAXHOSTNAME+1]; int wake_up_interval; int num_fds, nfound; unsigned long readfds; struct timeval timeout; time_t lt; int i_reuseaddr; port_number = 5001; verbose = FALSE; wake_up_interval = 0; for(i = 1; i < argc; ++i) { if(argv[i][0] != '-') continue; switch(argv[i][1]) { case 'w': case 'W': if(++i == argc) continue; wake_up_interval = atoi(argv[i]); break; case 'p': case 'P': if(++i == argc) continue; port_number = atoi(argv[i]); break; case 'v': case 'V': verbose = TRUE; break; } /* switch (argv..... */ } /* for(argn.... */ /* Get a socket */ if ((listen_socket = socket(AF_INET,SOCK_STREAM,0)) < 0) { tcperror("socket"); exit(1); } if (verbose) { printf("listen_socket = %i\n",listen_socket); } /* I want to reuse address */ i_reuseaddr = 1; if ( setsockopt( listen_socket, SOL_SOCKET, SO_REUSEADDR, (char *) &i_reuseaddr,sizeof(i_reuseaddr)) < 0 ) { tcperror("setsocketopt SO_REUSEADDR"); } /* Get the local host information */ (void)gethostname(localhost,MAXHOSTNAME); if((hp = gethostbyname(localhost)) == NULL) { fprintf(stderr,"Cannot get local host info?\n"); exit(1); } /* Set the things for the bind call */ sa.sin_addr.s_addr=INADDR_ANY; sa.sin_family = hp->h_addrtype; sa.sin_port=port_number; /* bind the socket */ if(bind(listen_socket,&sa,sizeof sa,0) < 0) { tcperror("bind"); exit(1); } listen(listen_socket,BACKLOG); /* print out a startup message */ printf("TSOSVR Version %s GSI / Darmatadt\n",VERSION); time(<); printf("Server started at %s\n",asctime(localtime(<))); /* Loop forever */ for (;;) { if (wake_up_interval != 0) { readfds |= (1 << listen_socket); timeout.tv_sec=wake_up_interval; nfound = select(listen_socket+1,&readfds,0,0,&timeout); if (nfound==0) { continue; } } /* wake_up_interval */ /* Just wait for someone to connect to us */ i = sizeof isa; if ((jcl_socket = accept(listen_socket,&isa,&i)) < 0) { tcperror("accept"); exit(1); } r_sa_lng = sizeof r_sa; if (getpeername(jcl_socket,&r_sa,&r_sa_lng) != 0) { tcperror("accept"); } strcpy(remote_host,inet_ntoa(r_sa.sin_addr.s_addr)); time(<); strcat(remote_host," on "); strcat(remote_host,asctime(localtime(<))); remote_host[strlen(remote_host)-1]='\0'; printf("\nConnection from %s.\n",remote_host); fflush(stdout); /* read and submit JCL */ if (read_submit(jcl_socket)) { /* readjcl will return 1 if special "stop-string" is received */ if ( close(listen_socket,2) < 0) { tcperror("close listen_socket"); } if ( close(jcl_socket,2) < 0) { tcperror("close jcl_socket"); } printf("Shutting down.\n"); fflush(stdout); fflush(stderr); exit(0); } /* all done close the jcl_socket, and go wait for the next connect */ if ( close(jcl_socket,2) < 0) { tcperror("close jcl_socket"); } if (verbose) { printf("jcl_socket is closed\n"); } fflush(stdout); fflush(stderr); } } int read_submit(sock) int sock; { char rmachine[80]; char ruser[80]; char rtty[80]; char mvs_userid[80]; char mvs_passwd[80]; char tso_cmd[80]; char cmvs_sport[80]; int mvs_sport; extern char asciitoebcdic[]; extern char ebcdictoascii[]; char cmd[80]; char command[80]; char jobname[80]; char servreply[80]; int i_open = 0; register char *c; FILE *jcl_output; int k; int j=0; int i; int ilines = 7; char *cntl??(??) = { "//TSO EXEC LGN001 \n", "//SYSIN DD DUMMY \n", "//SYSPRINT DD SYSOUT=T \n", "//SYSTERM DD SYSOUT=T \n", "//FT05F001 DD DUMMY \n", "//FT06F001 DD SYSOUT=T \n", "//SYSTSPRT DD SYSOUT=T \n", "//SYSTSIN DD * \n"}; if (verbose) { printf ("read_submit entered\n"); fflush(stdout); } /* read strings from socket */ if ( getstr(sock,rmachine,sizeof(rmachine),"rmachine") <= 0) { sprintf(servreply,"Error: Problem in getting rmachine"); goto bad; } if ( getstr(sock,ruser,sizeof(ruser),"ruser") <= 0) { sprintf(servreply,"Error: Problem in getting ruser"); goto bad; } if ( getstr(sock,rtty,sizeof(rtty),"rtty") <= 0) { sprintf(servreply,"Error: Problem in getting rtty"); goto bad; } if ( getstr(sock,mvs_userid,sizeof(mvs_userid),"mvs_userid") <= 0) { sprintf(servreply,"Error: Problem in getting mvs_userid"); goto bad; } if ( getstr(sock,mvs_passwd,sizeof(mvs_passwd),"mvs_passwd") <= 0) { sprintf(servreply,"Error: Problem in getting mvs_passwd"); goto bad; } if ( getstr(sock,tso_cmd,sizeof(tso_cmd),"tso_cmd") <= 0) { sprintf(servreply,"Error: Problem in getting tso_cmd"); goto bad; } if ( getstr(sock,cmvs_sport,sizeof(cmvs_sport),"cmvs_sport") <= 0) { sprintf(servreply,"Error: Problem in getting cmvs_sport"); goto bad; } CMXLATE(rmachine,asciitoebcdic,strlen(rmachine)); CMXLATE(ruser,asciitoebcdic,strlen(ruser)); CMXLATE(rtty,asciitoebcdic,strlen(rtty)); CMXLATE(mvs_userid,asciitoebcdic,strlen(mvs_userid)); CMXLATE(mvs_passwd,asciitoebcdic,strlen(mvs_passwd)); CMXLATE(tso_cmd,asciitoebcdic,strlen(tso_cmd)); CMXLATE(cmvs_sport,asciitoebcdic,strlen(cmvs_sport)); c = mvs_passwd; while (*c) { if (islower(*c)) *c = toupper(*c); c++; } c = mvs_userid; while (*c) { if (islower(*c)) *c = toupper(*c); c++; } mvs_sport = atoi(cmvs_sport); if (verbose) { printf ("We have read from socket\n"); printf ("rmachine : %s \n",rmachine); printf ("ruser : %s \n",ruser); printf ("rtty : %s \n",rtty); printf ("mvs_userid : %sē\n",mvs_userid); printf ("tso_cmd : %s \n",tso_cmd); printf ("mvs_sport : %i \n",mvs_sport); fflush(stdout); } /* test of mvs_userid/mvs_passwd */ if (chpass(mvs_userid,mvs_passwd) <0 ){ sprintf(servreply, "Bad user and/or password for user %s.",mvs_userid) ; goto bad; } /* shutting down */ if ((!strncmp(mvs_userid,"RZ",2) || !strncmp(mvs_userid,"RS",2)) && !strncmp(tso_cmd,"tsosubend",9) ) { sprintf(servreply,"Shutting down TSOSUB."); j = 1; goto bad; } /* add sport to tso command, if sport == 0 */ if (mvs_sport == 0 ) { if( ++sport >= PORTMAX ) sport = PORTMIN; sprintf(command,"%s %d",tso_cmd,sport); sprintf(cmvs_sport,"%i",sport); } else { strcpy(command,tso_cmd); } if (verbose) { printf(" command = %s\n",command); } /* open jcl_output_dsn */ if ((jcl_output=fopen(JCL_OUTPUT_DSN, "w,blksize=3120,lrecl=80,recfm=fb")) == NULL) { sprintf(servreply, "Error: MVS-Server: Could not open %s (help data-set on MVS)", JCL_OUTPUT_DSN); goto bad; } i_open = 1; /* add job card */ if( ++jobnumber >= 100 ) jobnumber = 0; sprintf(jobname,"%sTS%02i",mvs_userid,jobnumber); fprintf(jcl_output, "//%s JOB CLASS=B,MSGCLASS=T,REGION=7000K,\n",jobname); fprintf(jcl_output, "// USER=%s,PASSWORD=%s\n",mvs_userid,mvs_passwd); /* write to jcl_output_dsn */ for ( i = 0 ; i <= ilines ; i++ ) { fprintf(jcl_output,"%s",cntl??(i??)); } /* add command */ if (!fprintf(jcl_output,"%s\n",command)) { sprintf(servreply, "Error: MVS-Server: TSO-Command could not be added to CNTL"); goto bad; } i_open = 0; /* close jcl_output_dsn */ if (( fclose(jcl_output)) != 0 ) { sprintf(servreply, "Error: MVS-Server: Could not close %s (help data-set on MVS)", JCL_OUTPUT_DSN); goto bad; } /* submit jcl_output_dsn */ sprintf(cmd,"submit %s ",JCL_OUTPUT_DSN); if (system(cmd) != 0) { sprintf(servreply, "Error: MVS-Server: System call (submit) ended with an error"); goto bad; } sprintf(servreply,"Job %s submitted on MVS",jobname); bad: /* close jcl_output_dsn */ if (i_open) { if (( fclose(jcl_output)) != 0 ) { fprintf(stderr, "Error: MVS-Server: Could not close %s (help data-set on MVS)" , JCL_OUTPUT_DSN); } } if (verbose) { printf("servreply =%s\n",servreply); } CMXLATE(cmvs_sport,ebcdictoascii,strlen(cmvs_sport)); CMXLATE(servreply,ebcdictoascii,strlen(servreply)); /* send client sport,servreply */ if ( send(sock, cmvs_sport, strlen(cmvs_sport) + 1, 0) < 0) { tcperror("Send sport "); exit(1); } if ( send(sock, servreply, strlen(servreply) + 1, 0) < 0) { tcperror("Send servreply "); exit(1); } return(j); } /* This routines are copied from tcpaw to tsosubd. * They are : getstr chpass chpas reply */ /* * read a string from the socket (sock). * * Returns: Number of bytes in the string * -1 for an error */ getstr(sock,buf, cnt, errmesg) int *sock; char *buf; int cnt; /* sizeof() the char array */ char *errmesg; /* in case error message required */ { char c; int k = 0; do { if ( read(sock, &c, 1) != 1) { printf("Error or EOF while reading %s from socket.\n", errmesg); return(-1); /* error or EOF */ } *buf++ = c; k++; if (--cnt == 0) { printf("%s too long from socket.\n", errmesg); return(-1); } } while (c!= 0); /* null byte terminates the string */ return(k-1); } int chpass(user, pass) /* For IBM */ char *user, *pass; { char *topoint; int i; topoint = user; while (*topoint != '\0'){ toupper(*topoint); topoint++; } topoint = pass; while (*topoint != '\0'){ toupper(*topoint); topoint++; } if (CHPAS(user,pass)){ /*if pw check no ok (done in assembler) */ reply("Bad user/password for %s.\n", user); return(-3); } reply("User %s accepted.\n", user); return(1); } int CHPAS(user, pass) /* For IBMMVS */ char *user, *pass; { int i; char cmd??(80??); i = sprintf(cmd,"TSOEXEC PWDCHK2 %s,%s",user,pass); i = system(cmd); /* i = 0 user,pass ok */ /* i = 4 user,pass not ok */ return(i); } reply(s1, s2, s3) char *s1, *s2, *s3; { printf(s1, s2, s3); fflush(stdout); } #endif