"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 }