"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "logserial-0.4.2/logserial.c" of archive logserial-0.4.2.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 //
2 // Program for loging input on a serial port
3 //
4 // Copyright (c) 1998,2000 Sinkovics Zoltan
5 //
6 // Released under the conditions of the GNU General
7 // Public License.
8 //
9
10 #include "logserial.h"
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <ctype.h>
16 #include <signal.h>
17 #include <sys/time.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <errno.h>
21 #include <string.h>
22 //*#include <lockdev.h>
23
24 #define MAXPATH 255
25
26 char NAME[MAXPATH]; // program name
27 int outfd; // output file descriptor
28 int infd; // input file descriptor
29 int portfd; // serial port file descriptor
30 int pipefd; // named pipe file descriptor
31
32 //*char myTTY[MAXPATH]; // tty device name as a global variable
33
34 void closetty(int sig) ;
35 void version(void) ;
36 void usage(void) ;
37
38 void version(void)
39 {
40 fprintf(stdout,"\n%s-%s by Sinkovics Zoltan \n\n",NAME,VERSION);
41 }
42
43 void usage(void)
44 {
45 fprintf(stderr,"\n %s-%s\n\n",NAME,VERSION);
46 fprintf(stderr," usage: %s [parameters]\n",NAME);
47 fprintf(stderr,"\tOptional parameters are:\n");
48 fprintf(stderr,"\t\t -h prints this help screen\n");
49 fprintf(stderr,"\t\t -v prints version of %s\n",NAME);
50 fprintf(stderr,"\t\t -t tty \t default /dev/ttyS1\n");
51 fprintf(stderr,"\t\t -s speed \t default 9600\n");
52 fprintf(stderr,"\t\t -d data bits \t default 8\n");
53 fprintf(stderr,"\t\t -p parity \t default N\n");
54 fprintf(stderr,"\t\t -c if exists software handshake used (by default hw used)\n");
55 fprintf(stderr,"\t\t -f output file\t default /dev/stdout\n");
56 fprintf(stderr,"\t\t -b if exists logserial run as a daemon\n");
57 fprintf(stderr,"\t\t -r if exists logserial run in reverse mode\n");
58 fprintf(stderr,"\t\t -n filename \t specify input named pipe in reverse mode\n");
59 fprintf(stderr,"\t\t -a use this option if you will read output file wit DOS\n");
60 fprintf(stderr,"\t\t -u umask\t specify umask for logserial\n");
61 fprintf(stderr,"\t\t -m mask \t specify file creation mode for logserial\n\n");
62 }
63
64 int main(int argc, char **argv)
65 {
66 int c,childproc;
67 char tty[MAXPATH]; // serial port tty
68 char baudrate[10]; // baud rate as a string
69 char parity[10]; // parity as a string
70 char bits[10]; // data bits as a string
71 int hwhandshake=1; // true if RTS/CTS handshake used
72 int swhandshake=0; // true if XON/XOFF handshake used
73 char fileout[MAXPATH]; // output file
74 char filein[MAXPATH]; // input file
75 char filepipe[MAXPATH]; // name of the named pipe
76 struct stat filestatus; // status of the output file
77 int daemonize=0; // true if daemonize is enabled
78 int reverse=0; // true if reverse mode selected
79 int named_pipe=0; // true if name pipe mode used
80 int dos_converter=0; // true if dos converter mode is active
81 int n; // just for the for
82 mode_t um=0; // default umask
83 mode_t rwxmode ; // read,write,execute rights
84
85 fd_set fds; // file descriptor set for reading
86 fd_set fds_out; // file descriptor set for writing
87 struct timeval tv; // struct for time interval for select
88 int buflen ; // length of buffer
89 char buf[128] ; // input character buffer
90 FILE* input_stream=NULL ; // input file descriptor as a stream
91 //* pid_t dev_locked; // tty lockfile flag
92
93 strcpy(fileout , "/dev/stdout" );
94 strcpy(filein , "/dev/stdin" );
95 strcpy(filepipe , "/tmp/trypipe");
96 strcpy(bits , "8" );
97 strcpy(parity , "N" );
98 strcpy(baudrate , "9600" );
99 strcpy(tty , "/dev/ttyS1" );
100 strcpy(NAME , "logserial" );
101
102 rwxmode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH ;
103
104 /* parse command line */
105 while ((c = getopt (argc, argv, "t:s:d:p:f:cvhbrn:au:m:")) != EOF)
106 {
107 switch (c)
108 {
109 case 'h': // help
110 usage();
111 exit(EXIT_SUCCESS);
112 break;
113 case 'v': // version
114 version();
115 exit(EXIT_SUCCESS);
116 break;
117 case 't': // tty
118 if (strlen(optarg) > (MAXPATH-1))
119 {
120 fprintf(stderr,"Too long tty path arg!!\n");
121 exit(EXIT_FAILURE);
122 }
123 strcpy(tty, optarg);
124 break;
125 case 's': // speed
126 if (strlen(optarg)>9)
127 {
128 fprintf(stderr,"Too long baudrate arg!!\n");
129 exit(EXIT_FAILURE);
130 }
131 strcpy (baudrate, optarg);
132 break;
133 case 'd': // data
134 if (strlen(optarg)>9)
135 {
136 fprintf(stderr,"Too long bit number arg!!\n");
137 exit(EXIT_FAILURE);
138 }
139 strcpy (bits, optarg);
140 break;
141 case 'p': // parity
142 if (strlen(optarg)>9)
143 {
144 fprintf(stderr,"Too long parity arg!!\n");
145 exit(EXIT_FAILURE);
146 }
147 strcpy (parity, optarg);
148 break;
149 case 'c': // flow control (handshake)
150 swhandshake=1;
151 hwhandshake=0;
152 break;
153 case 'f': // output file
154 if (strlen(optarg)>(MAXPATH-1))
155 {
156 fprintf(stderr,"Too long output file arg!!\n");
157 exit(EXIT_FAILURE);
158 }
159 strcpy(fileout, optarg);
160 break;
161 case 'b':
162 daemonize=1;
163 break;
164 case 'r':
165 reverse=1;
166 break;
167 case 'n':
168 if (strlen(optarg) > (MAXPATH-1))
169 {
170 fprintf(stderr,"Too long named pipe path arg!!\n");
171 exit(EXIT_FAILURE);
172 }
173 strcpy(filepipe, optarg);
174 named_pipe=1;
175 reverse=1;
176 break;
177 case 'a':
178 dos_converter=1;
179 break;
180 case 'u':
181 sscanf(optarg,"%o",&um) ;
182 umask(um) ;
183 break ;
184 case 'm':
185 sscanf(optarg,"%o",&rwxmode) ;
186 break ;
187 }
188 }
189
190 // daemonize now if requested...
191
192 if(daemonize==1) {
193 childproc=fork();
194 if(childproc==-1) {
195 perror("Unable to fork");
196 exit(EXIT_FAILURE);
197 }
198 if(childproc!=0) {
199 fprintf(stderr,"Started logserial daemon...\n");
200 exit(EXIT_SUCCESS);
201 }
202 }
203
204 if(named_pipe)
205 {
206 // unlink(filepipe);
207 //umask(0);
208 pipefd = mknod(filepipe, S_IFIFO|rwxmode, 0);
209 if ( pipefd != -1 )
210 {
211 fprintf(stderr,"%s created successfully.",filepipe);
212 }
213 else
214 {
215 if ((pipefd == -1) && (errno == EEXIST))
216 {
217 fprintf(stderr,"%s already exists. Will use it.\n",filepipe);
218 }
219 else
220 {
221 fprintf(stderr,"Error creating %s. Exiting.\n",filepipe);
222 exit(EXIT_FAILURE);
223 }
224 }
225 }
226
227 if (!reverse)
228 {
229 // makes new file if logfile not exists, if exists append log to it
230
231 outfd = open(fileout,O_WRONLY|O_CREAT|O_APPEND,rwxmode);
232
233 if (outfd == -1)
234 {
235 fprintf(stderr,"Can't open %s for writing.\n",fileout);
236 exit(EXIT_FAILURE);
237 }
238 }
239 else
240 {
241 if (named_pipe)
242 {
243 strcpy(filein,filepipe);
244 }
245
246 infd = open(filein, O_RDONLY);
247
248 if (infd == -1)
249 {
250 fprintf(stderr,"Can't open %s for reading.\n",fileout);
251 exit(EXIT_FAILURE);
252 }
253
254 if (!named_pipe)
255 {
256 input_stream = fdopen(infd,"r");
257 }
258 }
259
260 //* // Let's see if the serial port is locked
261 //* dev_locked = dev_lock( tty ) ;
262 //*
263 //* if (dev_locked > 0) {
264 //* fprintf(stderr,"Can't get a lock on %s. Process # %d has it locked\n",tty ,dev_locked) ;
265 //* close(outfd) ;
266 //* exit(EXIT_FAILURE) ;
267 //* }
268 //* else if (dev_locked < 0) {
269 //* fprintf(stderr,"Can't get a lock on %s. Unknown error. Sorry!\n",tty) ;
270 //* close(outfd) ;
271 //* exit(EXIT_FAILURE) ;
272 //* }
273 //* else {
274 //* // There is program locking this tty already.
275 //* // Let's try opening the tty.
276
277 portfd = open(tty,O_RDWR);
278
279 if (portfd == -1)
280 {
281 fprintf(stderr,"Can't open %s .\n",tty);
282 close(outfd);
283 exit(EXIT_FAILURE);
284 }
285 //* }
286 m_savestate(portfd);
287
288 m_setparms(portfd,baudrate,parity,bits,hwhandshake,swhandshake);
289
290 m_nohang(portfd);
291
292 m_hupcl(portfd,1);
293
294 m_flush(portfd);
295
296 //* // Stow our tty name in a global variable
297 //* // so we can remove the lock when the program exits.
298 //* strcpy(myTTY, tty) ;
299
300 signal (SIGHUP, &closetty);
301 signal (SIGINT, &closetty);
302 signal (SIGQUIT, &closetty);
303 signal (SIGTERM, &closetty);
304 signal (SIGABRT, &closetty);
305
306 if (!reverse)
307 fprintf(stderr,"Successfully opened %s. Start loging.\n",tty);
308 else
309 fprintf(stderr,"Successfully opened %s. Start sending.\n",tty);
310
311 while(1)
312 {
313 if (!reverse)
314 {
315 tv.tv_sec=1 ; // 1 second
316 tv.tv_usec=0 ;
317
318 FD_ZERO(&fds );
319 FD_SET(portfd, &fds);
320
321 if (select(portfd+1, &fds, NULL, NULL, &tv) > 0)
322 {
323 buflen = read(portfd, buf, 127);
324 if (buflen == -1) closetty(-1);
325 if (buflen > 0 ) // got input bytes
326 {
327 if (stat(fileout , &filestatus)==-1) // This makes a new file if the logfile was deleted.
328 {
329 outfd = open(fileout,O_WRONLY|O_CREAT,rwxmode);
330 if (outfd == -1)
331 {
332 fprintf(stderr,"Output file was deleted, can't create new %s for writing.\n",fileout);
333 close(portfd);
334 exit(EXIT_FAILURE);
335 }
336 }
337 if (!dos_converter)
338 {
339 if (write(outfd, buf, buflen) != buflen) closetty(-2) ; // and put it onto output
340 }
341 else
342 for(n=0;n < buflen;n++)
343 {
344 write(outfd, buf+n, 1);
345 if (buf[n] == 0x0d)
346 {
347 buf[n] = 0x0a ;
348 write(outfd, buf+n, 1) ;
349 }
350 }
351 fsync(outfd);
352 }
353 }
354 }
355 else
356 {
357 if (named_pipe)
358 {
359 tv.tv_sec=1 ; // 1 second
360 tv.tv_usec=0 ;
361
362 FD_ZERO(&fds );
363 FD_SET(infd, &fds);
364
365 FD_ZERO(&fds_out );
366 FD_SET(portfd, &fds_out);
367
368 if (select(portfd+1, &fds, &fds_out, NULL, &tv) > 0)
369 {
370 if ( !FD_ISSET(infd, &fds))
371 {
372 continue;
373 }
374
375 if (!FD_ISSET(portfd, &fds_out))
376 {
377 continue;
378 }
379
380 buflen = read(infd, buf, 8);
381
382 if (buflen == -1) closetty(-3);
383
384 if (buflen > 0 ) // got input bytes
385 {
386 if (write(portfd, buf, buflen) != buflen) closetty(-4) ; // and put it onto output
387 fsync(outfd);
388 }
389 }
390 }
391 else
392 {
393 tv.tv_sec=1 ; // 1 second
394 tv.tv_usec=0 ;
395
396 FD_ZERO(&fds );
397 FD_SET(infd, &fds);
398
399 FD_ZERO(&fds_out );
400 FD_SET(portfd, &fds_out);
401
402 if (select(portfd+1, &fds, &fds_out, NULL, &tv) > 0)
403 {
404 if ( !FD_ISSET(infd, &fds))
405 {
406 continue;
407 }
408
409 if (!FD_ISSET(portfd, &fds_out))
410 {
411 continue;
412 }
413
414 buflen = read(infd, buf, 8);
415
416 if (buflen == -1) closetty(-3);
417
418 if (buflen > 0 ) // got input bytes
419 {
420 if (write(portfd, buf, buflen) != buflen) closetty(-4) ; // and put it onto output
421 fsync(outfd);
422 }
423
424 if (buflen==0)
425 {
426 fprintf(stderr,"No more input. Exiting\n");
427 exit(EXIT_SUCCESS);
428 }
429 }
430 }
431 }
432 }
433 return(0);
434 }
435
436 void closetty(int sig)
437 {
438 //* pid_t temp_lock ;
439
440 switch (sig) {
441 case -1:
442 fprintf(stderr,"Read error on tty. Closing communication port\n");
443 break;
444 case -2:
445 fprintf(stderr,"Write error on output. Closing communication port\n");
446 break;
447 case -3:
448 fprintf(stderr,"Read error on input file. Closing communication port\n");
449 break;
450 case -4:
451 fprintf(stderr,"Write error on tty. Closing communication port\n");
452 break;
453 default:
454 fprintf(stderr,"Got signal %d. Closing communication port\n",sig);
455 break;
456 }
457
458 //* temp_lock = dev_unlock( myTTY, getpid() );
459
460 m_restorestate(portfd);
461
462 close(portfd);
463
464 close(outfd);
465 close(infd);
466 close(pipefd);
467 exit(EXIT_SUCCESS);
468 }