⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 condevs.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifndef lintstatic  char    *sccsid = "@(#)condevs.c	4.2  Ultrix  9/7/90";#endif lint/************************************************************************ *                                                                      * *                      Copyright (c) 1983-1990 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.     * *                                                                      * ************************************************************************//* * Here are various dialers to establish the machine-machine connection. * conn.c/condevs.c was glued together by Mike Mitchell. * The dialers were supplied by many people, to whom we are grateful. * * --------------------------------------------------------------------- * NOTE: * There is a bug that occurs at least on PDP11s due to a limitation of * setjmp/longjmp.   If the routine that does a setjmp is interrupted * and longjmp-ed to,  it loses its register variables (on a pdp11). * What works is if the routine that does the setjmp * calls a routine and it is the *subroutine* that is interrupted. * * Anyway, in conclusion, condevs.c is plagued with register variables * that are used inside *      if (setjmp(...)) { *              .... *      } * * THE FIX: In dnopn(), for example, delete the 'register' Devices *dev. * (That was causing a core dump; deleting register fixed it.) * Also for dnopn delete 'register' int dnf... . * In pkopn, delete 'register' flds... . * There may be others, especially mcm's version of hysopen. * You could just delete all references to register, that is safest. * This problem might not occur on 4.1bsd, I am not sure. *      Tom Truscott * * Larry Cohen - 4/11/85 - add shared line code. * * marc@decvax - Add ability for diropn to request which protocol to use. * * lp@decvax - Added generic dialer interface 2/22/85 * * decvax!larry - revamped df03/df02 code , should run on ULTRIX/11. * *              - cleaned up hayes smartmodem code,  resets before trying, *                      converts dialer characters to standard uucp dialing *                      characters. * *              - split out external definitions for dialing routines.  Should *                 be possible to add new dialer code without recompiling other *                 source modules (except condefs.c). * *              - only df02/03, hayes, and direct connect code *                    has been tested significantly. * */#include <sys/types.h>#include <errno.h>#include <setjmp.h>#include <signal.h>#include <sgtty.h>#include "uucp.h"#include <sys/file.h>extern int Dcf; /* so clsacu will work */extern char devSel[];   /* name to pass to delock() in close */extern int errno, next_fd;extern jmp_buf Sjbuf;extern int alarmtr();int nulldev(), nodev(), Acuopn(), diropn(), dircls();/*** *      nulldev         a null device (returns CF_DIAL) */int nulldev(){	return(CF_DIAL);}/*** *      nodev           a null device (returns CF_NODEV) */int nodev(){	return(CF_NODEV);}/* * The first things in this file are the generic devices. * Generic devices look through L-devices and call the CU_open routines for * appropriate devices.  Some things, like the Unet interface, or direct * connect, do not use the CU_open entry.  ACUs must search to find the' * right routine to call. *//*** *      diropn(flds)    connect to hardware line *      char *flds[]; * *      return codes: *              >0  -  file number  -  ok *              FAIL  -  failed */diropn(flds)register char *flds[];{	register int dcr, status;	int ret;	struct Devices dev;	char dcname[20];	char msg[50];	FILE *dfp;	dfp = fopen(DEVFILE, "r");	ASSERT(dfp != NULL, "CAN'T OPEN", DEVFILE, 0);nextd:  while ((status = rddev(dfp, &dev)) != FAIL) {		if (strcmp(flds[F_CLASS], dev.D_class) != SAME)			continue;		if (strcmp(flds[F_PHONE], dev.D_line) != SAME)			continue;		if (mlock(dev.D_line) != FAIL)			break;	}	if (status == FAIL) {		fclose(dfp);		return(CF_NODEV);	}	/* Does this line want to use a different protocol ? */	if (dev.D_proto[0] != '\0')		Prefproto = dev.D_proto[0];	sprintf(dcname, "/dev/%s", dev.D_line);	if (setjmp(Sjbuf)) {		delock(dev.D_line);		fclose(dfp);		return(FAIL);	}	signal(SIGALRM, alarmtr);	alarm(10);	getnextfd();	errno = 0;#ifdef ONDELAY	dcr = open(dcname, O_RDWR|O_NDELAY); /* read/write */#else	dcr = open(dcname, 2); /* read/write */#endif	next_fd = -1;	if (dcr < 0 && errno == EACCES)		logent(dcname, "CAN'T OPEN");	if (dcr < 0 && errno == EBUSY) {		logent(dcname, "Direct line already in use");		goto nextd;	}	fclose(dfp);	alarm(0);	if (dcr < 0) {		delock(dev.D_line);		return(FAIL);	}#ifdef ULTRIX	if (ioctl(dcr, TIOCSINUSE)<0 && errno==EALREADY) {		logent(dcname, "SHARED LINE IN USE");		close(dcr);		delock(dev.D_line);		return(FAIL);	}	{	/*	 * The following code occurs throughout condevs.c in about	 * a dozen places.  The old code did a getpgrp() call to get	 * the current process group, then did the TIOCSPGRP to set	 * the modem line to match that of the current process (us).	 * This fails when programs (illegally) open /dev/console and	 * assign it a process group, such that subsequent daemons which	 * start up from the console terminal will inherit the bogus	 * process group.  The dnet_spawner and /usr/lib/lpd are two	 * of the known culprits.  Our workaround is to set our process	 * group to our own pid, and use that instead.	 */	int pgrp = getpid(); /* XXX: was getpgrp(), not getpid() */	int temp = 0;	ret=setpgrp(pgrp, pgrp); /* XXX: first pgrp is really our pid */	if (ret < 0)		DEBUG(6,"setpgrp failed, errno=%d\n", errno);	/* ensure correct process group if run in background by cron */	ioctl(dcr, TIOCSPGRP, &pgrp);#ifdef ONDELAY	/* ignore modem signals - reset to default mode on last close */	ret = ioctl(dcr, TIOCNMODEM, &temp);	if (ret < 0)		DEBUG(6,"ioctl(TIOCNMODEM), errno=%d\n", errno);#endif	}#endif	fflush(stdout);	fixline(dcr, dev.D_speed);	strcpy(devSel, dev.D_line);     /* for latter unlock */	sprintf(msg, "%s, fd= %d",devSel, dcr);	logent(msg, "using device");	CU_end = dircls;	return(dcr);}dircls(fd)register int fd;{	if (fd > 0) {		ioctl(fd, TIOCCINUSE);		close(fd);		delock(devSel);		}	}#ifdef DATAKIT#include <dk.h>#define DKTRIES 2/*** *      dkopn(flds)     make datakit connection * *      return codes: *              >0 - file number - ok *              FAIL - failed */dkopn(flds)char *flds[];{	int dkphone;	register char *cp;	register ret, i;	if (setjmp(Sjbuf))		return(FAIL);	signal(SIGALRM, alarmtr);	dkphone = 0;	cp = flds[F_PHONE];	while(*cp)		dkphone = 10 * dkphone + (*cp++ - '0');	DEBUG(4, "dkphone (%d) ", dkphone);	for (i = 0; i < DKTRIES; i++) {		getnextfd();		ret = dkdial(D_SH, dkphone, 0);		next_fd = -1;		DEBUG(4, "dkdial (%d)\n", ret);		if (ret > -1)			break;	}	return(ret);}#endif#ifdef PNET/*** *      pnetopn(flds) * *      call remote machine via Purdue network *      use dial string as host name, speed as socket number * Author: Steve Bellovin */pnetopn(flds)char *flds[];{	int fd;	int socket;	register char *cp;	fd = pnetfile();	DEBUG(4, "pnet fd - %d\n", fd);	if (fd < 0) {		logent("AVAILABLE DEVICE", "NO");		return(CF_NODEV);	}	socket = 0;	for (cp = flds[F_CLASS]; *cp; cp++)		socket = 10*socket + (*cp - '0');	DEBUG(4, "socket - %d\n", socket);	if (setjmp(Sjbuf)) {		DEBUG(4, "pnet timeout  - %s\n", flds[F_PHONE]);		return(FAIL);	}	signal(SIGALRM, alarmtr);	DEBUG(4, "host - %s\n", flds[F_PHONE]);	alarm(15);	if (pnetscon(fd, flds[F_PHONE], socket) < 0) {		DEBUG(4, "pnet connect failed - %s\n", flds[F_PHONE]);		return(FAIL);	}	alarm(0);	return(fd);}#endif  PNET#ifdef UNET/*** *      unetopn -- make UNET (tcp-ip) connection * *      return codes: *              >0 - file number - ok *              FAIL - failed *//* Default port of uucico server */#define DFLTPORT        33unetopn(flds)register char *flds[];{	register int ret, port;	int unetcls();	port = atoi(flds[F_PHONE]);	if (port <= 0 || port > 255)		port = DFLTPORT;	DEBUG(4, "unetopn host %s, ", flds[F_NAME]);	DEBUG(4, "port %d\n", port);	if (setjmp(Sjbuf)) {		logent("tcpopen", "TIMEOUT");		endhnent();     /* see below */		return(CF_DIAL);	}	signal(SIGALRM, alarmtr);	alarm(30);	ret = tcpopen(flds[F_NAME], port, 0, TO_ACTIVE, "rw");	alarm(0);	endhnent();     /* wave magic wand at 3com and incant "eat it, bruce" */	if (ret < 0) {		DEBUG(5, "tcpopen failed: errno %d\n", errno);		logent("tcpopen", "FAILED");		return(CF_DIAL);	}	CU_end = unetcls;	return(ret);}/* * unetcls -- close UNET connection. */unetcls(fd)register int fd;{	DEBUG(4, "UNET CLOSE called\n", 0);	if (fd > 0) {		/* disable this until a timeout is put in		if (ioctl(fd, UIOCCLOSE, STBNULL))			logent("UNET CLOSE", "FAILED");		 */		close(fd);		DEBUG(4, "closed fd %d\n", fd);	}}#endif UNET#ifdef MICOM/* *      micopn: establish connection through a micom. *      Returns descriptor open to tty for reading and writing. *      Negative values (-1...-7) denote errors in connmsg. *      Be sure to disconnect tty when done, via HUPCL or stty 0. */micopn(flds)register char *flds[];{	extern errno;	char *rindex(), *fdig(), dcname[20];	int dh, ok = 0, speed;	register struct condev *cd;	register FILE *dfp;	struct Devices dev;	dfp = fopen(DEVFILE, "r");	ASSERT(dfp != NULL, "Can't open", DEVFILE, 0);	signal(SIGALRM, alarmtr);	dh = -1;	for(cd = condevs; ((cd->CU_meth != NULL)&&(dh < 0)); cd++) {		if (snccmp(flds[F_LINE], cd->CU_meth) == SAME) {			fseek(dfp, (off_t)0, 0);			while(rddev(dfp, &dev) != FAIL) {				if (strcmp(flds[F_CLASS], dev.D_class) != SAME)					continue;				if (snccmp(flds[F_LINE], dev.D_type) != SAME)					continue;				if (mlock(dev.D_line) == FAIL)					continue;				sprintf(dcname, "/dev/%s", dev.D_line);				getnextfd();				alarm(10);				if (setjmp(Sjbuf)) {					delock(dev.D_line);					logent(dev.D_line,"micom open TIMEOUT");					dh = -1;					break;					}				dh = open(dcname, 2);				alarm(0);				next_fd = -1;				if (dh > 0) {					break;					}				devSel[0] = '\0';				delock(dev.D_line);				}			}		}	fclose(dfp);	if (dh < 0)		return(CF_NODEV);	speed = atoi(fdig(flds[F_CLASS]));	fixline(dh, speed);	sleep(1);	/* negotiate with micom */	if (speed != 4800)      /* damn their eyes! */		write(dh, "\r", 1);	else		write(dh, " ", 1);	DEBUG(4, "wanted %s ", "NAME");	ok = expect("NAME", dh);	DEBUG(4, "got %s\n", ok ? "?" : "that");	if (ok == 0) {		write(dh, flds[F_PHONE], strlen(flds[F_PHONE]));		sleep(1);		write(dh, "\r", 1);		DEBUG(4, "wanted %s ", "GO");		ok = expect("GO", dh);		DEBUG(4, "got %s\n", ok ? "?" : "that");	}	if (ok != 0) {		if (dh > 2)			close(dh);		DEBUG(4, "micom failed\n", "");		delock(dev.D_line);		return(CF_DIAL);	} else		DEBUG(4, "micom ok\n", "");	CU_end = cd->CU_clos;	strcat(devSel, dev.D_line);     /* for later unlock */	return(dh);}miccls(fd)register int fd;{	if (fd > 0) {		close(fd);		delock(devSel);		}	}#endif MICOM/*** *      Acuopn - open an ACU and dial the number.  The condevs table *              will be searched until a dialing unit is found that is *              free. * *      return codes:   >0 - file number - o.k. *                      FAIL - failed */char devSel[20];        /* used for later unlock() */#ifdef GENERICchar gbuf[1024];#endifAcuopn(flds)register char *flds[];{    char phone[MAXPH+1];    register struct condev *cd, *gencd, *tcd;    register int fd;    register FILE *dfp;    struct Devices dev;    char msg[100];    int ret = CF_NODEV;    extern int gendialer;    int havebrand, isgen;    exphone(flds[F_PHONE], phone);    devSel[0] = '\0';    DEBUG(4, "Dialing %s\n", phone);    dfp = fopen(DEVFILE, "r");    ASSERT(dfp != NULL, "Can't open", DEVFILE, 0);    for(cd = condevs; cd->CU_meth != NULL; cd++) {	if (prefix(cd->CU_meth, flds[F_LINE])) {	    fseek(dfp, (off_t)0, 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -