/* KERMSRV Kermit-11 server for Bitnet on node UOFT02 */ /* Interface to Jnet */ /* */ /* 23-APR-1985 09:02 Brian Nelson */ /* */ /* Edits: */ /* */ /* 29-APR-1985 BDN Fix DIR command if no argument (force *.*) */ /* 30-APR-1985 BDN Check $STATUS after DIR and SEND. Add SET NOON */ /* 11-SEP-1985 BDN Fix bugs introduced with VAX C v2 (and bad code)*/ /* 02-Apr-1986 BDN Jnet version 2 mods */ /* */ /* */ /* */ /* */ /* $ cc kermsrv */ /* $ link kermsrv+jan_sys:bitlib/lib */ /* $ cop kermsrv.exe jan_sys: */ /* $ cp */ /* define kermsrv/link/daemon=kermsrv */ /* start kermsrv */ /* $ exit */ /* */ /* Runs as a detached process for user KERMSRV. All replies are */ /* either terminal messages or batch jobs accessing the jnet SEND */ /* command. */ #include #include #include #define then extern char *getmsg(),*malloc(),*strchr() , *strcat() , *strcpy() , *tmpnam() ; extern char *upcase() ; int vmserror ; struct dsc { int len ; char *addr ; } ; FILE *infile ; char sysmsg[257] ; char kermsrv[] = "KERMSRV " ; char kermsrv_dir[] = "SYS$SYSROOT:[KERMSRV]" ; main(argc,argv) int argc ; char *argv[] ; { char msg[100],buffer[80],opmsg[140] ; int msglen,status ; char node[10],user[10] ; struct dsc nodedsc = { 8,&node } ; struct dsc userdsc = { 8,&user } ; struct dsc msgbuf = { 100,&msg } ; struct dsc opdsc = { 120,&opmsg } ; $DESCRIPTOR(nulldsc,"\0") ; $DESCRIPTOR(local_node,"UOFT02") ; $DESCRIPTOR(local_user,"KERMSRV") ; $DESCRIPTOR(local_msguser,"BRIAN") ; int mode ; mode = 2 ; if ( jan_daemon_init(&local_user) == 0 ) then return(0) ; while (1) { if ( (status=jan_receive_msg(&mode,&nodedsc,&userdsc ,&msgbuf,&msglen))==0 ) then sys$hiber() ; else if ( mode != 2 ) { msgbuf.len = msglen&0377 ; str$concat(&opdsc,&nodedsc,&userdsc,&msgbuf,&nulldsc) ; sendopcom(opdsc.addr) ; *(nodedsc.addr+(nodedsc.len&0377)) = 0 ; *(userdsc.addr+(userdsc.len&0377)) = 0 ; *(msgbuf.addr+ (msgbuf.len&0377)) = 0 ; upcase(msgbuf.addr) ; docommand(nodedsc.addr,userdsc.addr,msgbuf.addr) ; msgbuf.len = 100 ; } } } #define TEXTFILE 1 #define JNETDUMP 2 docommand(node,user,msgbuf) char *node,*user,*msgbuf ; { #define SEND 1 #define HELP 2 #define DIR 3 #define SENT 4 #define VMSDUMP 5 struct cmdtype { char command[8] ; int index ; } ; static struct cmdtype cmdlist[] = { "SEND",SEND, "HELP",HELP, "DIR" ,DIR , "SENT",SENT, "VMS" ,VMSDUMP, "VMSDUMP",VMSDUMP, "" ,0 } ; struct cmdtype *cmdp ; char *s,*d,cmd[100],arg[100] ; int i ; d = cmd ; s = msgbuf ; while ( *s == ' ' ) s++ ; while ( *s && *s != ' ' ) *d++ = *s++ ; *d = 0 ; while ( *s == ' ' ) s++ ; d = arg ; while ( (*d = *s++) != 0 && *d != ' ') d++ ; *d = 0 ; i = 0 ; cmdp = &cmdlist[0] ; while ( cmdp->command[0] != 0 && strcmp(cmd,cmdp->command) != 0 ) cmdp++ ; switch( cmdp->index ) { case SEND: sendfile(arg,node,user,TEXTFILE) ; break ; case VMSDUMP: sendfile(arg,node,user,JNETDUMP) ; break ; case DIR: senddir(arg,node,user) ; break ; case HELP: sendhelp(arg,node,user) ; break ; case SENT: /* Ignore messages for file forwarding */ break ; default: sendbad(cmd,node,user) ; break ; } } /* SENDDIR send a directory listing to remote */ senddir(f,node,user) char *f ; char *node,*user ; { char tmpout[100],tmpcom[100] ; char cmd[133] ; char s[256],*cp,*dp ; struct dsc cmdline ; int flags,i,m ; m = 2 ; cp = f ; dp = s ; for ( i=strlen(f); i > 0; i-- ) if ( (*dp = *cp++) > ' ' ) then dp++ ; *dp = 0 ; if ( s[0] == 0 ) then strcpy(s,"*.*") ; if ( checksyntax(s) == 0 ) then { sendmsg(node,user,"Bad filename syntax or access violation"); return(vmserror=0) ; } else { strcpy(tmpcom,kermsrv_dir) ; strcpy(tmpout,kermsrv_dir) ; strcat(tmpcom,tmpnam(cmd)) ; strcat(tmpout,tmpnam(cmd)) ; strcat(tmpcom,".COM") ; strcat(tmpout,".LIS") ; if ( ( infile = fopen(tmpcom,"w") ) == NULL ) then { vmserror = 0 ; return(0) ; } else { sendmsg(node,user,"The file will be sent shortly") ; fputs("$ SET NOON\012",infile) ; fputs("$ dq = \"\"\"\012",infile) ; strcpy(cmd,"$ DIR/SIZE/DATE/OUT=") ; strcat(cmd,tmpout) ; strcat(cmd," ") ; strcat(cmd,"KERBIN:,KER:") ; strcat(cmd,s) ; strcat(cmd,"\012") ; fputs(cmd,infile) ; fputs("$ dirstatus = $STATUS\012",infile) ; fputs("$ if dirstatus then goto sendit\012",infile) ; fputs("$ erm = dq + f$mes(dirstatus) + dq\012",infile); strcpy(cmd,"$ SEND/REM ") ; strcat(cmd,node) ; strcat(cmd," ") ; strcat(cmd,user) ; strcat(cmd," 'erm\012") ; fputs(cmd,infile) ; fputs("$ exit\012",infile) ; fputs("$sendit:\012",infile) ; strcpy(cmd,"$ SEND/FILE ") ; strcat(cmd,tmpout) ; strcat(cmd," ") ; strcat(cmd,user) ; strcat(cmd,"@") ; strcat(cmd,node) ; strcat(cmd,"\012") ; fputs(cmd,infile) ; fclose(infile) ; vmserror = sendbatch(tmpcom,0) ; } } return(vmserror & 1) ; } sendfile(s,node,user,type) char *s ; char *node,*user ; int type ; { char tmpcom[100] ; char cmd[133] ,*cmd_name ; int flags,wild ; char text_com[] = "$ SEND/FILE KER:" ; char bin_com[] = "$ SEND/FILE/VMSDUMP KERBIN:" ; if ( checksyntax(s) == 0 ) then { sendmsg(node,user,"Bad filename syntax or access violation"); return(vmserror=0) ; } ; wild = 0 ; if ( strchr(s,'*') != 0 ) then { sendmsg(node,user,"Your request will not be honored until") ; sendmsg(node,user,"23:00 hours EST since your filename is") ; sendmsg(node,user,"wildcarded") ; wild = 1 ; } ; if ( strchr(s,'.') == 0 ) then { sendmsg(node,user,"Please include an explicit filetype") ; sendmsg(node,user,"As in: SEND K11*.MAC or SEND AA*.TXT") ; return(0) ; } ; if ( strcmp(s,"*.*") == 0 ) then { sendmsg(node,user,"Please wildcard FILENAME or FILETYPE only"); sendmsg(node,user,"as there are over 60,000 blocks of Kermit"); sendmsg(node,user,"files on this node") ; return(0) ; } else if ( findfile(s,type) == 0 ) then sendmsg(node,user,getmsg(vmserror)) ; else { sendmsg(node,user,"The file(s) will be sent shortly") ; strcpy(tmpcom,kermsrv_dir) ; strcat(tmpcom,tmpnam(cmd)) ; strcat(tmpcom,".COM") ; cmd_name = ( type == JNETDUMP ) ?bin_com:text_com ; if ( ( infile = fopen(tmpcom,"w") ) == NULL ) then { vmserror = 0 ; return(0) ; } else { fputs("$ SET NOON\012",infile) ; fputs("$ dq = \"\"\"\012",infile) ; strcat(strcpy(cmd,cmd_name),s) ; strcat(cmd," ") ; strcat(cmd,user) ; strcat(cmd,"@") ; strcat(cmd,node) ; strcat(cmd,"\012") ; fputs(cmd,infile) ; fputs("$ sts = $STATUS\012",infile) ; fputs("$ if sts then goto ex\012",infile) ; fputs("$ erm = dq+f$mes(sts)+dq\012",infile); strcpy(cmd,"$ SEND/REM ") ; strcat(cmd,node) ; strcat(cmd," ") ; strcat(cmd,user) ; strcat(cmd," 'erm\012") ; fputs(cmd,infile) ; strcpy(cmd,"$ SEND/FILE KER:NOTFOUND.TEXT "); strcat(strcat(strcat(cmd,user),"@"),node) ; fputs(strcat(cmd,"\012"),infile) ; fputs("$ex:\012",infile) ; fputs("$ exit\012",infile) ; fclose(infile) ; vmserror = sendbatch(tmpcom,wild) ; } } return(vmserror & 1) ; } sendhelp(s,node,user) char *s ; char *node,*user ; { sendmsg(node,user,"Commands are SEND file, DIR file, and VMSDUMP file") ; sendmsg(node,user,"VMSDUMP file can be used to get executable files in"); sendmsg(node,user,"jnet VMSDUMP format (ie, .EXE, .TSK, .SAV files).") ; } sendbad(s,node,user) char *s ; char *node,*user ; { struct dsc nd,ud,em ; char msg[133] ; strcpy(msg,"Unknown command UOFT02 Kermsrv - ") ; strcat(msg,s) ; sendmsg(node,user,msg) ; } sendmsg(node,user,msg) char *node,*user,*msg ; { struct dsc nd,ud,md ; int mode ; mode = 2 ; md.addr = msg ; md.len = strlen(msg) ; nd.addr = node ; nd.len = strlen(node) ; ud.addr = user ; ud.len = strlen(user) ; jan_send_msg(&mode,&nd,&ud,&md) ; } checksyntax(s) char *s ; { extern char *strchr() ; return( strchr(s,'[') == 0 && strchr(s,':') == 0 && strchr(s,'<') == 0 ) ; } findfile(f,type) char *f ; int type ; { /* Verify that at least one file will match the filename passed */ /* so that we can have some assurance that the batch job we submit */ /* to do the actual send will succeed. */ char fname[256] ; struct dsc$descriptor_s srcbuf ; struct dsc$descriptor_d resbuf ; int context,status ; $DESCRIPTOR(def_spec,"KER:*.*") ; $DESCRIPTOR(alt_spec,"KERBIN:*.*") ; strcpy(fname,f) ; if ( strchr(fname,'.') == 0 ) then strcat(fname,"*.*") ; context = 0 ; srcbuf.dsc$w_length = strlen( fname ) ; srcbuf.dsc$b_class = DSC$K_CLASS_S ; srcbuf.dsc$b_dtype = DSC$K_DTYPE_T ; srcbuf.dsc$a_pointer = fname ; resbuf.dsc$w_length = 0 ; resbuf.dsc$b_class = DSC$K_CLASS_S ; resbuf.dsc$b_dtype = DSC$K_DTYPE_D ; resbuf.dsc$a_pointer = 0 ; switch (type) { case TEXTFILE: vmserror = lib$find_file(&srcbuf,&resbuf,&context,&def_spec) ; break ; case JNETDUMP: vmserror = lib$find_file(&srcbuf,&resbuf,&context,&alt_spec) ; break ; } ; lib$find_file_end(&context) ; return( vmserror & 1 ) ; } sendopcomdsc(s) struct dsc *s ; { char *m ; int slen ; slen = s->len & 0xFFFF ; if ( (m=malloc(slen + 1)) != 0 ) then { strncpy(m,s->addr,slen) ; m[slen] = 0 ; sendopcom(m) ; free(m) ; } ; } sendopcom(s) char *s ; /* Send a asciz message to opcom */ { struct opcfmt { unsigned char type ; short int target_0_15 ; unsigned char target_16_23 ; unsigned long rqstid ; char msg[80] ; } ; struct dsc { long length ; struct opcfmt *addr ; } ; struct opcfmt msgdsc ; struct dsc opmsg = { 80,&msgdsc } ; int reply_chan,status ; reply_chan = 0 ; msgdsc.type = OPC$_RQ_RQST ; msgdsc.target_0_15 = OPC$M_NM_CENTRL ; msgdsc.target_16_23 = 0 ; msgdsc.rqstid = 0 ; strcpy(msgdsc.msg,s) ; opmsg.length = 8 + strlen(msgdsc.msg) ; opmsg.addr = &msgdsc ; return( (vmserror=sys$sndopr(&opmsg,reply_chan)) & 1 ) ; } char *getmsg(n) int n ; { struct dsc msgd ; int mlen ; char junk[4] ; mlen = 0 ; msgd.len = 256 ; msgd.addr = sysmsg ; sys$getmsg(n,&mlen,&msgd,0,&junk) ; sysmsg[mlen] = 0 ; return( &sysmsg ) ; } sendbatch(f,late) char *f ; int late ; { #define SJC$_AFTER_TIME 3 #define SJC$_ENTER_FILE 19 #define SJC$_QUEUE 134 #define SJC$_FILE_SPECIFICATION 42 #define SJC$_NO_LOG_SPOOL 101 #define SJC$_NO_DELETE_FILE 25 #define SJC$_USERNAME 159 struct itmlst { short int buflen; short int code ; char *bufadr ; int *retlen ; } ; $DESCRIPTOR(latetime,"-- 23:00:00.00") ; static struct itmlst dobatch[10] ; int status,iosb[2],abstime[2] ; static char batch[] = "SYS$BATCH" ; sys$bintim(&latetime,&abstime) ; dobatch[0].buflen = strlen(batch) ; dobatch[0].code = SJC$_QUEUE ; dobatch[0].bufadr = &batch ; dobatch[0].retlen = 0 ; dobatch[1].buflen = strlen(f) ; dobatch[1].code = SJC$_FILE_SPECIFICATION ; dobatch[1].bufadr = f ; dobatch[1].retlen = 0 ; dobatch[2].buflen = 0 ; dobatch[2].code = SJC$_NO_LOG_SPOOL ; dobatch[2].bufadr = 0 ; dobatch[2].retlen = 0 ; dobatch[3].buflen = 12 ; dobatch[3].code = SJC$_USERNAME ; dobatch[3].bufadr = &kermsrv ; dobatch[3].retlen = 0 ; if (late) then { dobatch[4].buflen = 8 ; dobatch[4].code = SJC$_AFTER_TIME ; dobatch[4].bufadr = &abstime ; dobatch[4].retlen = 0 ; } else { dobatch[4].buflen = 0 ; dobatch[4].code = 0 ; } ; dobatch[5].buflen = 0 ; dobatch[5].code = 0 ; status = sys$sndjbcw(0,SJC$_ENTER_FILE,0,&dobatch,&iosb,0,0) ; return(iosb[0]) ; } char *upcase(s) char *s ; { char *cp ; cp = s ; while ( *cp ) { *cp = toupper(*cp) ; cp++ ; } ; return(s) ; } char *lowcase(s) char *s ; { char *cp ; cp = s ; while ( *cp ) { *cp = tolower(*cp) ; cp++ ; } ; return(s) ; }