📄 dial.c
字号:
#ifndef lintstatic char *sccsid = "@(#)dial.c 4.2 (ULTRIX) 9/4/90";#endif lint/************************************************************************ * * * Copyright (c) 1985 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * Modification History * * * * David L Ballenger, 30-Mar-1985 * * 0001 Port to ULTRIX environment * * * * 0002 Change savint and savhup to void for new handler definition * * * ************************************************************************//* @(#)dial.c 1.16 *//*LINTLIBRARY*//*************************************************************** * dial() returns an fd for an open tty-line connected to the * specified remote. The caller should trap all ways to * terminate, and call undial(). This will release the `lock' * file and return the outgoing line to the system. This routine * would prefer that the calling routine not use the `alarm()' * system call, nor issue a `signal(SIGALRM, xxx)' call. * If you must, then please save and restore the alarm times. * The sleep() library routine is ok, though. * * #include <sys/types.h> * #include <sys/stat.h> * #include "dial.h" * * int dial(call); * CALL call; * * void undial(rlfd); * int rlfd; * * rlfd is the "remote-lne file descriptor" returned from dial. * * The CALL structure as (defined in dial.h): * * typedef struct { * struct termio *attr; ptr to term attribute structure * int baud; transmission baud-rate * int speed; 212A modem: low=300, high=1200 * char *line; device name for out-going line * char *telno; ptr to tel-no digit string * char *device Will hold the name of the device * used to makes a connection. * int dev_len This is the length of the device * used to makes a connection. * } CALL; * * The error returns from dial are negative, in the range -1 * to -12, and their meanings are: * * INTRPT -1: interrupt occured * D_HUNG -2: dialer hung (no return from write) * NO_ANS -3: no answer within 20 seconds * ILL_BD -4: illegal baud-rate * A_PROB -5: acu problem (open() failure) * L_PROB -6: line problem (open() failure) * NO_Ldv -7: can't open L-devs file * DV_NT_A -8: specified device not available * DV_NT_K -9: specified device not known * NO_BD_A -10: no device available at requested baud-rate * NO_BD_K -11: no device known at requested baud-rate * DV_NT_E -12: requested speed does not match * * Setting attributes in the termio structure indicated in * the `attr' field of the CALL structure before passing the * structure to dial(), will cause those attributes to be set * before the connection is made. This can be important for * some attributes such as parity and baud. * * As a device-lockout semaphore mechanism, we create an entry, * in the directory #defined as LOCK, whose name is LCK..dev * where dev is the device name taken from the "line" column * in the file #defined as LDEVS. Be sure to trap every possible * way out of execution in order to "release" the device. * This entry is `touched' every hour in order to keep uucp * from removing it on its 90 minute rounds. * Also, have the system start-up procedure clean all such * entries from the LOCK directory. * * With an error return (negative value), there will not be * any `lock-file' entry, so no need to call undial(). ***************************************************************/#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <signal.h>#include <stdio.h>#include <string.h>#include <termio.h>#include <errno.h>#include "dial.h"#define DEV "/dev/"#define UPDTE 3600 /* how often to touch the lock entry */#define ACULAST "<" /* character which terminates dialing*/#define YES 1 /* mnemonic */#define NO 0 /* mnemonic */#define DIFFER strcmp /* mnemonic */#define say (void)fprintf /* mnemonic */extern unsigned sleep(), alarm();extern int errno;extern char *malloc();static char cul[15+sizeof(DEVDIR)] = DEV, /* line's device-name */ cua[15+sizeof(DEVDIR)] = DEV, /* acu's device-name */ *find_dev(), /* local function */ lock[16+sizeof(LOCK)]; /* directory in which to make lockfile*/static int sperfg=0, /* requested speed not available */ found=0, /* set when device is seen legal */ saverr, /* hide errno during other calls */ rlfd, /* fd for remote comm line */ lfd= -1, /* fd for the device-lock file */ intflag=NO, /* interrupt indicator */ connect(); /* local function */static void /* DAG */ intcatch(), /* interrupt routine */ alrmcatch(), /* interrupt routine */ hupcatch(); /* interrupt routine */#ifdef ddtstatic void dump();#endifchar device[34];int _debug=0;void undial();intdial(call)CALL call;{ FILE *Ldevices; /* file pointer for Device name file */ char dvc[30]; void (*savint)(), (*savhup)(); /* DAG */#ifdef ddt if(_debug == YES) { say(stderr, "call dial(%d)\r\n", call); dump(&call, 0); }#endif saverr = 0; savint = signal(SIGINT, intcatch); savhup = signal(SIGHUP, hupcatch); (void)signal(SIGALRM, alrmcatch); if(call.telno == NULL && call.line == NULL) { rlfd = DV_NT_K; goto OUT; } if((Ldevices = fopen(LDEVS, "r")) == NULL) { saverr = errno; rlfd = NO_Ldv; goto OUT; } while(1) { int xx; (void)strcpy(dvc, find_dev(Ldevices, &call)); if(strlen(dvc) == 0) goto F1; /* failure to find device */ (void)strcpy(lock, LOCK); (void)strcat(lock, dvc); /* creat will always succeed if usr-id is 0, so check that case separately */ if(geteuid() == 0 && access(lock, 0) == 0) goto F0; /* device found but busy */ if((lfd = creat(lock, 0444)) < 0) goto F0; /* device found but busy */ /* DAG -- bug fix as per Oct 1984 SUN: */ (void)chmod(lock, 0664); xx = getpid(); (void)write(lfd, (char*)&xx, sizeof(xx)); break; /* we have a device get out of here */ F0: if(!call.line) /* dial device is busy */ continue; /* try to find another */ F1: if(call.line) if(found) /* specific device request */ rlfd = DV_NT_A; else if(sperfg == 1) rlfd = DV_NT_E; else rlfd = DV_NT_K; else if(found) /* we are dialing */ rlfd = NO_BD_A; else rlfd = NO_BD_K; goto CLOUT; } if(intflag == YES) rlfd = INTRPT; else if((rlfd = connect(&call)) < 0) undial(rlfd); else (void)alarm(UPDTE);CLOUT: (void)fclose(Ldevices);OUT: (void)signal(SIGINT, savint); (void)signal(SIGHUP, savhup); errno = saverr; return(rlfd);}/*************************************************************** * connect: establish dial-out or direct connection. * Negative values returned (-1...-7) are error message indices. ***************************************************************/static intconnect(call)CALL *call;{ struct termio *lvp, lv; int er=0, dum, fdac, fd=0, t, w, x; char *p, sp_code, b[30];#ifdef ddt if(_debug == YES) { say(stderr, "call connect(%o)\n", call); dump(call, 0); }#endif switch(call->baud) { case 110: sp_code = (B110 | CSTOPB); break; case 134: sp_code = B134;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -