Address code analysis issues
[ric-plt/lib/rmr.git] / src / rmr / si / src / si95 / sipoll.c
1 // vim: noet sw=4 ts=4:
2 /*
3 ==================================================================================
4     Copyright (c) 2020 Nokia
5     Copyright (c) 2020 AT&T Intellectual Property.
6
7    Licensed under the Apache License, Version 2.0 (the "License");
8    you may not use this file except in compliance with the License.
9    You may obtain a copy of the License at
10
11        http://www.apache.org/licenses/LICENSE-2.0
12
13    Unless required by applicable law or agreed to in writing, software
14    distributed under the License is distributed on an "AS IS" BASIS,
15    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16    See the License for the specific language governing permissions and
17    limitations under the License.
18 ==================================================================================
19 */
20
21 /*
22 **************************************************************************
23 *  Mnemonic: SIpoll
24 *  Abstract: This routine will poll the sockets that are open for
25 *            an event and return after the delay period has expired, or
26 *            an event has been processed.
27 *  Parms:    gptr   - Pointer to the global information block
28 *            msdelay- 100ths of seconds to delay
29 *  Returns:  SI_OK if the caller can continue, SI_ERROR if all sessions have been
30 *            stopped, or the interface cannot proceed. When SI_ERROR is
31 *            returned the caller should cleanup and exit immediatly (we
32 *            have probably received a sigter or sigquit.
33 *  Date:     10 April 1995
34 *  Author:   E. Scott Daniels
35 *
36 **************************************************************************
37 */
38 #include  "sisetup.h"     //  get the setup stuff
39 #include "sitransport.h"
40 #include <wait.h>
41
42
43 extern int SIpoll( struct ginfo_blk *gptr, int msdelay )
44 {
45  //extern int deaths;       //  number of children that died and are zombies
46  //extern int sigflags;     //  flags set by the signal handler routine
47
48  int fd;                       //  file descriptor for use in this routine
49  int ((*cbptr)());             //  pointer to callback routine to call
50  int status = SI_OK;              //  return status
51  int addrlen;                  //  length of address from recvfrom call
52  char *buf;                    //  work buffer pointer
53  char ibuf[1025];
54  int i;                        //  loop index
55  struct tp_blk *tpptr;         //  pointer at tp stuff
56  struct tp_blk *nextone;        //  pointer at next block to process
57  int pstat;                    //  poll status
58  int kstat;                    //  keyboard status
59  struct timeval  delay;        //  delay to use on select call
60  struct sockaddr *uaddr;       //  pointer to udp address
61
62  if( gptr->flags & GIF_SHUTDOWN )     //  cannot do if we should shutdown
63   return( SI_ERROR );                    //  so just get out
64
65
66  if( gptr->magicnum != MAGICNUM )     //  if not a valid ginfo block
67   return( SI_ERROR );
68
69    delay.tv_sec = msdelay/100;                //  user submits 100ths, cvt to seconds and milliseconds
70    delay.tv_usec = (msdelay%100) * 10;
71
72
73    SIbldpoll( gptr );                 //  build the fdlist for poll
74    pstat = 0;                         //  ensure good code
75
76    if( gptr->fdcount > 0 )
77     pstat = select( gptr->fdcount, &gptr->readfds, &gptr->writefds,
78                                &gptr->execpfds, &delay );
79
80    if( (pstat < 0 && errno != EINTR)  )
81     {                             //  poll fail or termination signal rcvd
82      gptr->fdcount = 0;           //  prevent trying to look at a session
83      gptr->flags |= GIF_SHUTDOWN; //  cause cleanup and exit at end
84      //deaths = 0;                  //  dont need to issue waits on dead child
85      //sigflags = 0;                //  who cares about signals now too
86     }
87
88 /*
89    while( deaths > 0 )  //  there have been death(s) - keep the dead
90     {                   //  from being zombies - send them to heaven
91      wait( NULL );                       //  issue wait on child
92      deaths--;
93     }                   //  end while dead children to send to heaven
94 */
95
96 /*
97   if( sigflags &&        //  if signal received and processing them
98      (cbptr = gptr->cbtab[SI_CB_SIGNAL].cbrtn) != NULL )
99    {
100     while( sigflags != 0 )
101      {
102       i = sigflags;                  //  hold for call
103       sigflags = 0;                  //  incase we are interrupted while away
104       status = (*cbptr)( gptr->cbtab[SI_CB_SIGNAL].cbdata, i );
105       SIcbstat( gptr, status, SI_CB_SIGNAL );    //  handle status
106      }                                           //  end while
107    }
108 */
109
110    if( pstat > 0  &&  (! (gptr->flags & GIF_SHUTDOWN)) )
111     {
112      if( FD_ISSET( 0, &gptr->readfds ) )       //  check for keybd input
113       {
114        fgets( ibuf, 1024, stdin );   //  get the stuff from keyboard
115        if( (cbptr = gptr->cbtab[SI_CB_KDATA].cbrtn) != NULL )
116         {
117          status = (*cbptr)( gptr->cbtab[SI_CB_KDATA].cbdata, ibuf );
118          SIcbstat(  gptr, status, SI_CB_KDATA );    //  handle status
119         }                                 //  end if call back was defined
120       }
121
122      // for( tpptr = gptr->tplist; tpptr != NULL; tpptr = tpptr->next )
123      for( tpptr = gptr->tplist; tpptr != NULL; tpptr = nextone )
124         tpptr = gptr->tplist; 
125         while( tpptr != NULL ) {
126                 nextone = tpptr->next;                                  //  allow for a delete in loop
127
128        if( tpptr->squeue != NULL && (FD_ISSET( tpptr->fd, &gptr->writefds )) )
129         SIsend( gptr, tpptr );              //  send if clear to send
130
131        if( FD_ISSET( tpptr->fd, &gptr->execpfds ) )
132         {
133          ; //  sunos seems to set except for unknown reasons; ignore
134         }
135        else
136        if( FD_ISSET( tpptr->fd, &gptr->readfds ) )  //  read event pending?
137         {
138          fd = tpptr->fd;                     //  quick ref to the fd
139
140          if( tpptr->flags & TPF_LISTENFD )     //  listen port setup by init?
141           {                                    //  yes-assume new session req
142            status = SInewsession( gptr, tpptr );    //  make new session
143           }
144          else                              //  data received on a regular port
145           if( tpptr->type == SOCK_DGRAM )          //  udp socket?
146            {
147             uaddr = (struct sockaddr *) malloc( sizeof( struct sockaddr ) );
148             status = RECVFROM( fd, gptr->rbuf, MAX_RBUF, 0, uaddr, &addrlen );
149             if( status >= 0 && ! (tpptr->flags & TPF_DRAIN) )
150              {                                                           //  if good status call cb routine
151               if( (cbptr = gptr->cbtab[SI_CB_RDATA].cbrtn) != NULL )
152                {
153                 SIaddress( uaddr, (void **) &buf, AC_TODOT );
154                 status = (*cbptr)( gptr->cbtab[SI_CB_RDATA].cbdata, gptr->rbuf, status, buf );
155                 SIcbstat( gptr, status, SI_CB_RDATA );    //  handle status
156                                 free( buf );
157                }                              //  end if call back was defined
158              }                                //  end if status was ok
159             free( uaddr );
160            }                                  //  end if udp
161           else
162            {                                //  else receive on tcp session
163             status = RECV( fd, gptr->rbuf, MAX_RBUF, 0 );    //  read data
164
165             if( status > SI_OK  &&  ! (tpptr->flags & TPF_DRAIN) )
166              {
167               if( (cbptr = gptr->cbtab[SI_CB_CDATA].cbrtn) != NULL )
168                {
169                 status = (*cbptr)( gptr->cbtab[SI_CB_CDATA].cbdata, fd, gptr->rbuf, status );
170                 SIcbstat( gptr, status, SI_CB_CDATA );   //  handle cb status
171                }                            //  end if call back was defined
172              }                                     //  end if status was ok
173             else   //  sunos seems to send 0 bytes as indication of disc
174              {
175               if( (cbptr = gptr->cbtab[SI_CB_DISC].cbrtn) != NULL )
176                {
177                 status = (*cbptr)( gptr->cbtab[SI_CB_DISC].cbdata, tpptr->fd );
178                 SIcbstat( gptr, status, SI_CB_DISC );    //  handle status
179                }
180               SIterm( gptr, tpptr );
181             }
182            }                                                //  end tcp read
183         }                    //  end if event on this fd
184
185                 tpptr = nextone;
186       }                      //  end for each fd in the list
187     }                        //  end if not in shutdown
188
189
190  if( gptr->flags & GIF_SHUTDOWN )      //  we need to stop for some reason
191   {
192    status = SI_ERROR;                //  status should indicate to user to die
193    SIshutdown( gptr );            //  clean things up
194   }
195  else
196   status = SI_OK;                    //  user can continue to process
197
198  return( status );                //  send status back to caller
199 }                                 //  SIwait