]> git.sur5r.net Git - openldap/blob - libraries/msdos/lp.c
Fixed liblber ber_get_next trickle bug (ITS#2490)
[openldap] / libraries / msdos / lp.c
1 /*  -------------------------------------------------------------
2     lp.c
3
4     Routines common to lpr, lpq, and lprm.
5
6     Paul Hilchey    May 1989
7
8     Copyright (C) 1989  The University of British Columbia
9     All rights reserved.
10
11          history
12          -------
13          1/6/89   Microsoft C port by Heeren Pathak (NCSA)
14     -------------------------------------------------------------
15 */
16
17 #ifdef DOS
18 #ifndef PCNFS
19
20 #define LPR
21
22 #include <stdio.h>
23 #include <conio.h>
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #ifdef MEMORY_DEBUG
27 #include "memdebug.h"
28 #endif
29 #include "netevent.h"
30 #include "hostform.h"
31 #include "lp.h"
32 #include "externs.h"
33
34 #ifdef MSC
35 #define EXIT_FAILURE 1
36 #endif
37
38 void checkerr( void );
39
40 /****************************************************************
41  * lookup                                                       *
42  * Try to find the remote host in the local cache or from a     *
43  * domain name server.                                          *
44  * parameters: null terminated string containing the name or    *
45  *                ip address of the host                        *
46  * return value: pointer to machine info record, or 0 if the    *
47  *               lookup failed                                  *
48  ****************************************************************/
49 struct machinfo *lookup(char *host)
50 {
51         int what,dat;
52         int machine_number;     /* used to identify domain lookup events */
53         struct machinfo *machine_info;
54
55         machine_info = Sgethost(host);  /* look up in hosts cache */
56
57         if (!machine_info) {
58                 if ((machine_number = Sdomain(host)) < 0)
59                         return(0);  /* initiate domain name lookup */
60
61                 /* wait for DOMOK or DOMFAIL event */
62                 while (machine_info==NULL) {
63                         switch(lgetevent(USERCLASS,&what,&dat)) {
64                         case DOMFAIL:
65                                 /* lookup failed, return 0 */
66                                 return(0);
67                         case DOMOK:
68                                 /* get pointer to machine record */
69                                 machine_info=Slooknum(machine_number);
70                         default: 
71                                 break;
72                         }
73                 }
74                 if (debug) puts("Domain lookup worked");
75         }
76         return(machine_info);
77 }
78
79 /*****************************************************************
80  *  open_connection                                              *
81  *  Open the TCP connection.                                     *
82  *  parameters: pointer to machine info record                   *
83  *              source port number                               *
84  *              destination port number                          *
85  *  return value: connection identifier (port number), or -1 if  *
86  *                connection could not be opened                 *
87  *****************************************************************/
88 int open_connection(struct machinfo *machine_record, int source_port,
89 int dest_port)
90 {
91         int ev,what,dat;  /* parameters for lgetevent */
92         int conid;        /* connection identifier */
93
94         /* set the source port */
95         netfromport(source_port);
96
97         /* initiate connection open */
98         if (0 > (conid = Snetopen(machine_record,dest_port)))
99                 return(-1);
100
101         if (debug) puts("snetopen ok");
102
103         /* wait for connection to open or for attempt to fail */
104         while(1) {
105                 if (0 != (ev = lgetevent(CONCLASS,&what,&dat))) {
106                         if (dat != conid) {     /* not for us */
107                                 /*              netputevent(what,ev,dat); */
108                                 continue;
109                         }
110                         if (ev == CONOPEN)
111                                 break;
112                         else
113                                 return(-1);
114                 }
115         }
116         if (debug) puts("Conopen");
117         return(conid);
118 }
119
120
121 /*******************************************************************
122  * crash                                                           *
123  * Shut down all network stuff, print an error message to stderr,  *
124  * and abort.                                                      *
125  * parameters: variable length argument list for the error         *
126  *                message (a la printf)                            *
127  *******************************************************************/
128 void crash(char *msg,...)
129 {
130         va_list argptr;
131
132         fprintf(stderr,"\nError: ");
133         va_start(argptr,msg);
134         vfprintf(stderr,msg,argptr);
135         va_end(argptr);
136         fprintf(stderr,"\n");
137
138         /* shut everything down */
139         netshut();
140         exit(EXIT_FAILURE);
141 }
142
143 /*********************************************************************
144  * Check for any error events that may have occured.  Either print   *
145  * the message on stderr or just ignore it if it is probably not     *
146  * serious.  Set debug on to see all error messages.                 *
147  *********************************************************************/
148 void checkerr(void )
149 {
150         char *errmsg;
151         int i,j;
152
153         while (ERR1 == Sgetevent(ERRCLASS,&i,&j)) {
154                 if ((!debug) &&
155                     ((300 <= j && j <= 399) ||  /* IP messages */
156                 (400 <= j && j <= 499) ||       /* TCP messages */
157                 (600 <= j && j <= 699) ||       /* ICMP messages */
158                 j == 801  || j == 805  ||       /* misc. domain stuff */
159                 j == 806))
160                         continue;              /* just ignore them */
161                 errmsg = neterrstring(j);
162                 fprintf(stderr,"%s\n",errmsg);
163         }
164 }
165
166 /*********************************************************************
167  * lgetevent                                                         *
168  * Check for network events. The next pending non-error event is     *
169  * returned (if any).                                                *
170  * Takes the same parameters as sgetevent.                           *
171  *********************************************************************/
172 int lgetevent(int class, int *what, int *datp)
173 {
174         checkerr();
175         return(Sgetevent(class, what, datp));
176 }
177
178 /******************************************************************
179  * nprintf                                                        *
180  * Formatted write to an open TCP conection.  Like fprintf, but   *
181  * use a connection id returned from snteopen instead of a file   *
182  * handle.  The formatted string must not exceed 1023 bytes.      *
183  * Returns EOF if an error occurs                                 *
184  ******************************************************************/
185 int nprintf(int connection_id, char *format,...)
186 #define BUFF_SIZE 1024
187 {
188         va_list argptr;
189         char    buff[BUFF_SIZE], *buff_ptr;
190         int     len1, len2;
191
192         va_start(argptr,format);
193         len1 = vsprintf(buff,format,argptr);
194         va_end(argptr);
195         if ((len1 == EOF) || len1+1 >= BUFF_SIZE) return(EOF);
196         buff_ptr = buff;
197         while (buff_ptr < (buff + len1)) {
198                 len2 = netwrite(connection_id, buff_ptr,
199                     len1-(buff_ptr - buff));
200                 checkerr();
201                 Stask();
202                 if (len2 < 0) return(EOF);
203                 buff_ptr += len2;
204         }
205         if (debug) puts(buff);
206         return (len1);
207 }
208
209 /******************************************************************
210  * nread                                                          *
211  * Read from an open TCP connection.  Waits for incoming data if  *
212  * there is none in the queue.  Returns EOF if the connection     *
213  * closes and there is no more data.                              *
214  *                                                                *
215  * parameters: connection id returned by Snetopen                 *
216  *             buffer for returned data                           *
217  *             size of buffer                                     *
218  * returned value: number of characters read into the buffer      *
219  ******************************************************************/
220
221 int nread(int connection_id, char *buff, int buff_size)
222 {
223         int class,data,ev;
224         int len;
225
226         netpush(connection_id);  /* flush buffer */
227
228         while (0 == netest(connection_id)) {
229                 ev = lgetevent(CONCLASS, &class, &data);
230                 if (!ev) continue;
231                 if (data != connection_id) {   /* not for us; throw away */
232                         /*         netputevent(class, ev, data); */
233                         continue;
234                 }
235                 if (debug) printf("nread %d %d\n",class,ev);
236                 if (ev == CONDATA) {
237                         len = netread(connection_id,buff,buff_size);
238                         if (len == 0) continue;
239                         return (len);
240                 }
241         }
242         /* throw away other events.  getevent should be changed so we
243        can retrieve events for a selected port only  */
244         while (lgetevent(USERCLASS | CONCLASS, &class, &data));
245         return (EOF);    /* connection is closed and no data in queue */
246 }
247
248 #ifdef MSC
249 #else
250 #pragma warn .par
251 #endif
252
253 /******************************************************************
254  * breakstop                                                      *
255  * Handle break interrupts by shutting down the network stuff and *
256  * aborting.                                                      *
257  ******************************************************************/
258 int breakstop(void )
259 {
260         netshut();
261         return(0);
262 }
263
264 #endif PCNFS
265 #endif /* DOS */