#include "nntp.h" #include "netlib_dir:netlibdef.h" unsigned int shuttype = NETLIB_K_SHUTDOWN_BOTH, adrsize = sizeof(struct INADDRDEF), sinsize = sizeof(struct SINDEF); /* *-------------------------------------------------------------------------------- * Get line (string with CR/LF pair terminator). * Return status, and length of string in *bufl variable. */ int net_read_line ( void *chan, char *bufp, ushort *bufl, int *TimeOut ) { struct dsc$descriptor buf_dsc; int status; INIT_SDESC(buf_dsc,*bufl,bufp); return netlib_readline (&chan,&buf_dsc,bufl,0,TimeOut,0,0,0); } /* *-------------------------------------------------------------------------------- * Get multiline string (with CR/LF/.CR/LF terminator). * Return status, and length of string in *bufl variable. */ int net_read_mline ( void *chan, char *bufp, ushort *bufl, int *TimeOut ) { long status; ushort totlen = 0, flag,idx0 = 0; struct dsc$descriptor buf_dsc,trm_dsc,tmp_dsc; struct NETLIBIOSBDEF iosb; INIT_SDESC(trm_dsc,5,NNTP_EOM); INIT_SDESC(buf_dsc,*bufl,bufp); flag = NETLIB_M_FLUSH; status = netlib_readline (&chan,&buf_dsc,&totlen,&flag,TimeOut,&iosb,0,0); if ( totlen >= 5 ) { INIT_SDESC(tmp_dsc,totlen,bufp); if ( idx0 = str$position(&tmp_dsc,&trm_dsc) ) { *bufl = idx0; return (SS$_NORMAL); } } flag = 0; while (1) { do { INIT_SDESC(buf_dsc,(*bufl)-totlen,bufp+totlen); status = netlib_read (&chan,&buf_dsc,0,0,0,TimeOut,&iosb,0,0); if (!$VMS_STATUS_SUCCESS(status)) return status; if ( !iosb.iosb_w_count) continue; totlen +=iosb.iosb_w_count; if ( totlen >= 5 ) { INIT_SDESC(tmp_dsc,totlen,bufp); if ( idx0 = str$position(&tmp_dsc,&trm_dsc) ) { *bufl = idx0; return ( flag?SS$_INSFMEM:SS$_NORMAL); } } } while ( totlen < *bufl ); /* For getting rest of big messages. */ INIT_SDESC(buf_dsc,*bufl,bufp); flag = 5; str$copy_r(&buf_dsc,&flag,bufp+totlen-flag); if (!$VMS_STATUS_SUCCESS(status)) return status; totlen = flag; flag++; } return 0; } /* *-------------------------------------------------------------------------------- */ void net_close (void *network_context) { long status; if ( network_context ) { netlib_shutdown(&network_context,&shuttype,0,0,0); netlib_close(&network_context); }; } /* *-------------------------------------------------------------------------------- */ int net_connect_out ( void *chan, char *suck_host_name, ushort suck_host_len, ushort port ) { int status; struct dsc$descriptor dsc; struct SINDEF remsin; unsigned int remlen; INIT_SDESC(dsc, suck_host_len, suck_host_name); status = netlib_socket(chan); if (!$VMS_STATUS_SUCCESS(status)) return status; return netlib_connect_by_name(chan, &dsc, &port); } /* *-------------------------------------------------------------------------------- */ int net_connect_inc ( void *chan, ushort port, char *ipadr, ushort *ipadrlen, char *ipname, ushort *ipnamelen ) { long status; struct SINDEF remsin,locsin; unsigned int remlen,sinlen; static void *network_listener = NULL; struct dsc$descriptor adrdsc; struct NETLIBIOSBDEF iosb; if ( !network_listener ) { /* * Initialize passive socket */ memset(&locsin, 0, sinsize); port = (port?port:NNTP_TCPPORT); locsin.sin_w_port = netlib_hton_word(&port); status = netlib_socket(&network_listener); if (!$VMS_STATUS_SUCCESS(status)) return status; status = netlib_bind(&network_listener, &locsin, &sinsize); if (!$VMS_STATUS_SUCCESS(status)) return status; status = netlib_listen(&network_listener); if (!$VMS_STATUS_SUCCESS(status)) return status; } /* ** Wait incomming conection request */ status = netlib_accept(&network_listener, chan, &remsin, &sinsize, &sinlen,0, 0, 0); if ( !$VMS_STATUS_SUCCESS(status) ) return status; /* ** Get IP address and IP name of remote host */ INIT_SDESC(adrdsc, *ipnamelen, ipname); status = netlib_address_to_name(chan,0,&remsin.sin_x_addr,&adrsize, &adrdsc,ipnamelen,&iosb,0,0); if ( $VMS_STATUS_SUCCESS(status) ) { SET_SDESC(adrdsc, *ipnamelen, ipname); str$upcase(&adrdsc,&adrdsc); } SET_SDESC(adrdsc, *ipadrlen, ipadr); return netlib_addrtostr(&remsin.sin_x_addr,&adrdsc,ipadrlen); } /* *-------------------------------------------------------------------------------- */ int net_send_line ( void *chan, char *bufp, ushort bufl ) { struct dsc$descriptor buf_dsc; INIT_SDESC(buf_dsc,bufl,bufp); return (netlib_writeline (&chan,&buf_dsc,0,0,0,0,0)); } /* *-------------------------------------------------------------------------------- */ int net_send_cmd ( void *chan, char *cmd, ushort cmdl, char *bufp, ushort *bufl, ushort *rc, int *TimeOut ) { long status; struct dsc$descriptor buf_dsc; INIT_SDESC(buf_dsc,cmdl,cmd); status = netlib_writeline (&chan,&buf_dsc,0,0,0,0,0); if ( !$VMS_STATUS_SUCCESS(status) ) return status; INIT_SDESC(buf_dsc,*bufl,bufp); status = netlib_readline (&chan,&buf_dsc,bufl,0,TimeOut,0,0,0); if ( !$VMS_STATUS_SUCCESS(status) ) return status; if ( !lib$cvt_dtb(3,bufp,rc) ) return SS$_BADPARAM; return status; } /* *-------------------------------------------------------------------------------- */ int net_send_mline ( void *chan, char *bufp, ushort bufl ) { struct dsc$descriptor buf_dsc; INIT_SDESC(buf_dsc,bufl,bufp); netlib_write (&chan,&buf_dsc,0,0,0,0,0); INIT_SDESC(buf_dsc,5,NNTP_EOM); return netlib_write (&chan,&buf_dsc,0,0,0,0,0); } /* *-------------------------------------------------------------------------------- */ int net_ip_to_a ( int ipb, char *bufp, ushort *bufl ) { struct dsc$descriptor buf_dsc; INIT_SDESC(buf_dsc,*bufl,bufp); return netlib_addrtostr ((struct INADDRDEF *)&ipb,&buf_dsc,bufl); }