/* sethfc2.c set (or reset) hardware flow control on EPORTS This program sets (or resets) hardware flow control on an EPORTS card in an AT&T 3B2 computer. command line options: -C) open port with O_NDELAY (ignore status of DCD) -H X) hardware flow control flag where X = Y or N (for yes or no) ****** default value is HFC ON! -S) sleep 60 seconds after setting port -t N) set sleep time to N seconds -E) endless (daemon) mode argument list: 1-N) tty name(s): same as getty argument (tty24) 05/17/1993 - Elliot Dierksen (elliot@oau.org) 07/15/1993 - Elliot Dierksen. Added daemon mode, and -t option */ /* standard header files */ #include #include #include #include /* EPORTS header files */ #include #include #include #include #define MAX_OPT_ARGS 6 main(argc,argv,envp) int argc; char **argv,**envp; { extern char *optarg; extern int optind,opterr; char *usage = "usage: %s [-C] [-S] [-t N] [-E] [-H y|n] line [line...]\n"; char opt_args[MAX_OPT_ARGS][32], *devname; int c, tty_fd, oflag=O_RDWR, tty_count=0; int ep_flags; short errflag=0, hfc_flag=1, sleepflag=0, sleeptime=60, daemon=0; struct etty ettyp; struct termio termiop; /* initialize string variables to null */ for (c = 0; c < MAX_OPT_ARGS; c++) *opt_args[c] = '\0'; /* process options */ while ((c = getopt(argc,argv,"H:CSEt:")) != -1) switch (c) { /* sleep (sleeptime) seconds after setting port */ case 'S': sleepflag = 1; break; /* set sleep time to other than the default */ case 't': { int newtime; newtime = atoi(optarg); /* make sure that the time is at least 1 second */ if (newtime > 0) sleeptime = newtime; } break; /* set port endlessly (daemon mode) */ case 'E': /* force sleepflag on. otherwise, this process would eat the CPU alive!! */ sleepflag = 1; daemon = 1; break; /* ignore DCD when opening port */ case 'C': oflag |= O_NDELAY; break; /* hardware flow control flag */ case 'H': switch(*optarg) { /* turn HFC on */ case 'Y': case 'y': hfc_flag = 1; break; /* turn HFC off */ case 'N': case 'n': hfc_flag = 0; break; /* invalid argument, error out */ default: errflag++; break; } break; /* invalid argument or usage help requested */ case '?': errflag++; break; } /* show usage and exit if there was an error */ if (errflag) { fprintf(stderr,usage,argv[0]); fflush(stderr); exit(2); } /* load arguments */ for (c=0; optind < argc && c < MAX_OPT_ARGS; optind++, c++) { sprintf(opt_args[c],"/dev/%s",argv[optind]); tty_count++; } /* if we didn't get a tty name */ if (!tty_count) { /* can't run without a device, error out */ fprintf(stderr,usage,argv[0]); fflush(stderr); exit(4); } /* Here comes the meat of the program. Executed at least once. Endlessly if we are in daemon mode */ do { /* loop through the ports we have to process */ for (c = 0; c < tty_count; c++) { /* set our temp pointer to the device name */ devname = opt_args[c]; /* abort if we can't open the device */ if ((tty_fd = open(devname,oflag,0)) == -1) { fprintf(stderr,"%s: could not open %s(%d)\n",argv[0],devname,errno); fflush(stderr); exit(5); } /* abort if ioctl read fails. this might happen this is not an EPORT */ if (ioctl(tty_fd,EP_GETA,&ettyp) == -1) { fprintf(stderr,"%s: ioctl(EP_GETA) failed on %s(%d)\n",argv[0],devname,errno); fflush(stderr); exit(6); } /* abort if ioctl read fails. No clue what might have gone wrong! */ if (ioctl(tty_fd,TCGETA,&termiop) == -1) { fprintf(stderr,"%s: ioctl(TCGETA) failed on %s(%d)\n",argv[0],devname,errno); fflush(stderr); exit(7); } /* is HFC set? */ if (hfc_flag) { /* turn off XON/XOFF */ termiop.c_iflag &= ~(IXON|IXOFF|IXANY); /* set flag for HFC */ ep_flags = EP_HFC; } else { /* turn on XON/XOFF */ termiop.c_iflag |= (IXON|IXANY); /* set flag for SFC */ ep_flags = EP_NHFC; } /* set regular ioctl values */ ioctl(tty_fd,TCSETA,&termiop); /* set EPORTS values */ ioctl(tty_fd,ep_flags,0); /* close the port */ if (close(tty_fd) == -1) { fprintf(stderr,"%s: could not close %s(%d)\n",argv[0],devname,errno); fflush(stderr); exit(8); } } /* sleep if need be */ if (sleepflag) sleep(sleeptime); } while (daemon); exit(0); }