# /* skt_util.c */ /* globals declared in this file: n_s_left functions declared in this file: sm_dux sm_splx free_skt att_skt get_skt kill_skt init_skts clean_skt */ #include "files.h" #include "hstlnk.h" #include "socket.h" #include "globvar.h" #include "kwrite.h" /* SCCS PROGRAM IDENTIFICATION STRING */ char whatid_skt_util[] "~|^`skt_util.c\tV3.9E0\tJan78\n"; int n_s_left nsockets; /* counter for allocating sockets */ /*name: sm_dux function: given local and foreign base sockets, and a socket operation code ( init or listen), performs the operation on the pair of connections so defined, associating local with foreign+1 and local+1 with foreign. algorithm: compute local socket +1 via skt_off. compute foreign +1 via skt_off. do the operation to create a receive data socket using local and foreign+1 via sm_splx. do the operation to create a send data socket using local+1 and foreign via sm_splx. parameters: lbs_addr address of local base socket. fbs_addr address of foreign base socket. op socket operation code (must be si_init or si_glsn {in which case fbs_addr must be a legal address but the content is irrelevant} or si_slsn). returns: nothing. globals: ksx_rcv ksx_xmit calls: skt_off sm_splx called by: fi_sktnm kr_odrct fi_rfnm history: initial coding 1/6/75 by G. R. Grossman */ sm_dux(lbs_addr,fbs_addr,op) char *lbs_addr,*fbs_addr; int op; { char lskt_1[2], /* holds local socket +1 */ fskt_1[4]; /* holds foreign socket + 1 */ skt_off(&lbs_addr[2],&lskt_1[2],1,2); /* compute local socket +1 and store in lskt_1 */ /* perform operation creating send data socket */ sm_splx(&lskt_1[0],fbs_addr,ksx_xmit,op); skt_off(&fbs_addr[4],&fskt_1[4],1,4); /* compute foreign socket +1 and store in fskt_1 */ /* perform operation creating receive data socket */ sm_splx(lbs_addr,&fskt_1[0],ksx_rcv,op); } /*name: sm_splx function: creates a data socket given local and foreign sockets, socket type, and operation. algorithm: set fields of skt_req: file pointer from global fp. socket type from parameter sinx. operation from parameter op. byte size 8. host from global host. if receive: link number via asn_lnkn. otherwise (send): link number to "null" (0377) (1/10/75 GRG). local socket by copying thru parameter ls_addr. foreign socket by copying thru parameter fs_addr. create/match socket via get_skt. parameters: ls_addr pointer to local socket number. fs_addr pointer to foreign socket number. sinx socket type. op socket operation code (see remarks under parameters for sm_dux). returns: nothing. globals: fp host skt_req= calls: asn_lnkn get_skt called by: sm_dux kr_odrct history: initial coding 1/6/75 by G. R. Grossman null link # for send socket 1/10/75 by G. R. Grossman _ifdef SFHBYTE added variable bytesize 01/27/78 by S. F. Holmgren _endif */ sm_splx(ls_addr,fs_addr,sinx,op) char *ls_addr,*fs_addr; int sinx,op; { register char *sbp, /* source pointer for copying socket numbers */ *dbp; /* dest pointer for same */ register int n; /* counter for same */ skt_req.s_filep = fp; /* set file pointer */ skt_req.s_sinx = sinx; /* socket type */ skt_req.s_state = op; /* socket operation */ #ifndef SFHBYTE skt_req.s_bysz = 8; /* byte size */ #endif #ifdef SFHBYTE skt_req.s_bysz = (fp->f_bysz == 0) ? 8 : fp->f_bysz; /* byte size */ #endif skt_req.s_hstlnk.hl_host = host;/* host number */ if ( (ls_addr[1] & 1) == 0 ) /* receive socket? */ skt_req.s_hstlnk.hl_link = asn_lnkn(); /* assign link number */ else /* send socket */ skt_req.s_hstlnk.hl_link = 0377; /* "null link #" */ dbp = &skt_req.s_lskt[0]; /* set dest for socket number copy */ sbp = ls_addr; /* ditto for source */ *dbp++ = *sbp++; /* 1st byte of local socket */ *dbp++ = *sbp++; /* 2nd " " " " */ sbp = fs_addr; /* set source for foreign socket */ for (n = 4 ; n ; --n ) /* copy loop */ *dbp++ = *sbp++; get_skt(); /* go do it to the socket */ } /*name: free_skt function: detaches a socket from its file and de-allocates it. algorithm: if the socket is attached to a file: detach via fi_sgone. increment socket allocation counter. set socket state to null ( this makes it available). parameters: skt_p pointer to socket struct to be detached and deallocated. returns: nothing. globals: n_s_left= calls: fi_sgone called by: cls_q cls_clsw clo_lsn clo_c2cw history: initial coding 1/6/75 by G. R. Grossman modified by greep to clear timeout */ free_skt(skt_p) struct socket *skt_p; { register struct socket *s_p; s_p = skt_p; s_p->s_timeo = 0; /* clear timeout value */ if ( s_p->s_filep != 0 ) /* attached to file? */ fi_sgone(s_p); /* detach */ n_s_left =+ 1; /* increment socket allocation counter */ s_p->s_state = ss_null; /* set struct to null state, thus deallocating it */ } /*name: att_skt function: attaches a socket to its file. algorithm: the file pointer is obtained from the socket struct. the file's appropriate f_skt_x byte is set according to the socket's s_sinx field and the socket struct's index. the file's attached socket counter is incremented. parameters: skt_p pointer to socket struct to be attached to its file. returns: nothing. globals: sockets calls: nothing. called by: lsint_q so_ulsn history: initial coding 1/6/75 by G. R. Grossman */ att_skt(skt_p) struct socket *skt_p; { register struct socket *s_p; /*points to socket struct */ register struct file *f_p; /* points to associated file struct */ s_p = skt_p; f_p = s_p->s_filep; /* get pointer to file */ f_p->f_skt_x[s_p->s_sinx] = s_p - &sockets[0]; /* set appropriate socket index in file; we use C's conversion facilities to compute index */ f_p->f_nsatt++; /* increment file's attached socket count */ } /*name: get_skt function: attempts to fulfill the request in skt_req by finding a socket struct in sockets whose local socket matches that is skt_req and calling the appropriate procedure thrugh skt_oper. if the above fails, calls the appropriate procedure through so_unm. algorithm: loop through all socket structs: if the socket state is not null and the local sockets match: if the procedure called through skt_oper indexed by the states of skt_req and the current socket returns a non-zero value: return. if all socket structs are exhausted without terminating: call "unmatch" procedure through so_unm indexed by state of skt_req. parameters: none. returns: nothing. globals: sockets skt_oper skt_req so_unm calls: those procedures pointed to by: skt_oper so_unm called by: hr_rfc hr_cls kr_ouicp sm_splx kr_osicp history: initial coding 1/6/75 by G. R. Grossman */ get_skt() { register struct socket *p; /* will point to socket structs as we examine them */ for ( p = &sockets[0] ; p < &sockets[nsockets] ; p++ ) /* loop thru all skts */ if ( (p->s_state != ss_null) /* socket in use? */ && (p->s_lskt->word == skt_req.s_lskt->word) ) /* and locals match? */ if ( (*skt_oper[skt_req.s_state][p->s_state])(p) ) /* did op procedure return non-zero? */ return; /* all done if so */ (*so_unm[skt_req.s_state])(p); /* if fell out of loop, no match, call appropriate unmatched proc */ } /*name: kill_skt function: performs the "kill" operation on a socket. this operation is used when the ncp daemon spontaneously decides to close a connection without prior close action by the user program or the foreign host. algorithm: the appropriate procedure is called by indexing skt_oper with the kill op code and the state of the socket. parameters: skt_p pointer to the socket struct to be killed. returns: nothing. globals: skt_oper si_kill calls: "kill" procedures in skt_oper. called by: fi_sktnm fi_sgone fi_all fi_rfnm ir_re_x history: initial coding 1/6/75 by G. R. Grossman */ kill_skt(skt_p) struct socket *skt_p; { (*skt_oper[si_kill][skt_p->s_state])(skt_p); } /*name: init_skts function: initializes socket structs at program initialization. algorithm: loop thru all socket structs: set socket state to null. parameters: none. returns: nothing. globals: sockets nsockets ss_null calls: nothing. called by: main history: initial coding 1/8/75 by G. R. Grossman */ init_skts() { register struct socket *s_p; /* will point to sockets as we initialize them */ for ( s_p = &sockets[0] ; s_p < &sockets[nsockets] ; s_p++ ) /* loop thru all socket structs */ s_p->s_state = ss_null; /* set state to null */ } /*name: clean_skt function: clean up the local socket number clean up the foreign socket number clcean up the host and link numbers algorithm: if state is ss_clow zero things of awhile parameters: skt_p - address of a socket to be cleaned returns: nothing globals: none calls: nothing called by: cls_rfcw cls_cacw so_ut1 so_ut2 history: initial coding 7/7/76 by S. F. Holmgren */ clean_skt( skt_p ) struct socket *skt_p; { register char *sp; if( skt_p->s_state == ss_clow ) /* close wait? */ for( sp = skt_p; sp < &skt_p->s_state; *sp++ = 0 ); }