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

📄 dial.c

📁 VT100终端程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * dial.c	Functions to dial, retry etc. Als contains the dialing *		directory code, _and_ the famous tu-di-di music. * *		This file is part of the minicom communications package, *		Copyright 1991-1995 Miquel van Smoorenburg. * *		This program is free software; you can redistribute it and/or *		modify it under the terms of the GNU General Public License *		as published by the Free Software Foundation; either version *		2 of the License, or (at your option) any later version. */#include "port.h"#include "minicom.h"#if VC_MUSIC#  if defined(__linux__)#    include <sys/ioctl.h>#    include <sys/kd.h>#    include <sys/time.h>#  endif#  if defined(_COH42) || defined(_SCO)#    include <sys/vtkd.h>#  endif#endif/* We want the ANSI offsetof macro to do some dirty stuff. */#ifndef offsetof#  define offsetof(type, member) ((int) &((type *)0)->member)#endif/* Values for the "flags". */#define FL_ECHO		0x01	/* Local echo on/off. */#define FL_DEL		0x02	/* Backspace or DEL */#define FL_WRAP		0x04	/* Use autowrap. */#define FL_ANSI		0x08	/* Type of term emulation */#define FL_TAG		0x80	/* This entry is tagged. */#define FL_SAVE		0x0f	/* Which portions of flags to save. *//* Dialing directory. */struct v1_dialent {  char name[32];  char number[16];  char script[16];  char username[32];  char password[32];  char term;  char baud[8];  char parity[2];  char dialtype;  char flags; /* Localecho in v0 */  char bits[2];  struct dialent *next;};struct dialent {  char name[32];  char number[32];  char script[32];  char username[32];  char password[32];  char term;  char baud[8];  char parity[2];  char dialtype;  char flags;  char bits[2];  struct dialent *next;};/* Version info. */#define DIALMAGIC 0x55AAstruct dver {  short magic;  short version;  short size;  short res1;  short res2;  short res3;  short res4;};#define dialentno(di, no) ((struct dialent *)((char *)(di) + ((no) * sizeof(struct dialent))))  static struct dialent *dialents;static struct dialent *d_man;static int nrents = 1;static int newtype;/* Access to ".dialdir" denied? */static int dendd = 0;static char *tagged;/* * Functions to talk to the modem. */ /* * Send a string to the modem. * If how == 0, '~'  sleeps 1 second. * If how == 1, "^~" sleeps 1 second. */void mputs(s, how)char *s;int how;{  char c;  while(*s) {  	if (*s == '^' && (*(s + 1))) {  		s++;  		if (*s == '^')  			c = *s;  		else if (how == 1 && *s == '~') {			sleep(1);			s++;			continue;		} else  			c = (*s) & 31;  	} else  		c = *s;	if (how == 0 && c == '~')  		sleep(1);  	else	  		write(portfd, &c, 1);  	s++;  }}  /* * Initialize the modem. */ void modeminit(){  WIN *w;  if (P_MINIT[0] == '\0') return;  w = tell("Initializing Modem");  m_dtrtoggle(portfd);  mputs(P_MINIT, 0);  wclose(w, 1);}/* * Reset the modem. */void modemreset(){  WIN *w;  if (P_MRESET[0] == '\0') return;  w = tell("Resetting Modem");  mputs(P_MRESET, 0);  sleep(1);  wclose(w, 1);}/* * Hang the line up. */void hangup(){  WIN *w;  w = tell("Hanging up");  if (P_MDROPDTR[0] == 'Y') {  	m_dtrtoggle(portfd);  } else {  	mputs(P_MHANGUP, 0);  	sleep(1);  }  /* If we don't have DCD support fake DCD dropped */  bogus_dcd = 0;  wclose(w, 1);}/* * This seemed to fit best in this file * Send a break signal. */void sendbreak(){  WIN *w;    w = tell("Sending BREAK");  wcursor(w, CNONE);  m_break(portfd);  wclose(w, 1);}  WIN *dialwin;int dialtime;#if VC_MUSIC/* * Play music until key is pressed. */void music(){  int x, i, k;  int consolefd = 0;  char *disp;  /* If we're in X, we have to explicitly use the console */  if (strncmp(getenv("TERM"), "xterm", 5) == 0 &&	(disp = getenv("DISPLAY")) != NULL &&	(strcmp(disp, ":0.0") == 0 ||	(strcmp(disp, ":0") == 0))) {	consolefd = open("/dev/console", O_WRONLY);	if (consolefd < 0) consolefd = 0;  }  /* Tell keyboard handler what we want. */  keyboard(KSIGIO, 0);  /* And loop forever :-) */  for(i = 0; i < 9; i++) {	k = 2000 - 200 * (i % 3);	(void) ioctl(consolefd, KIOCSOUND, k);	/* Check keypress with timeout 160 ms */	x = check_io(-1, 0, 160, NULL, NULL);	if (x & 2) break;  }  (void) ioctl(consolefd, KIOCSOUND, 0);  if (consolefd) close(consolefd);  /* Wait for keypress and absorb it */  while((x & 2) == 0) x = check_io(-1, 0, 10000, NULL, NULL);  (void) keyboard(KGETKEY, 0);}#endif/* * The dial has failed. Tell user. * Count down until retrytime and return. */static int dialfailed(s, rtime)char *s;int rtime;{  int f, x;  int ret = 0;  wlocate(dialwin, 1, 5);  wprintf(dialwin, "    No connection: %s.      \n", s);  if (rtime < 0) {  	wprintf(dialwin, "   Press any key to continue..    ");	if (check_io(-1, 0, 10000, NULL, NULL) & 2) 		(void) keyboard(KGETKEY, 0);  	return(0);  }  wprintf(dialwin, "     Retry in %2d seconds             ", rtime);    for(f = rtime - 1; f >= 0; f--) {	x = check_io(-1, 0, 1000, NULL, NULL);	if (x & 2) {		/* Key pressed - absorb it. */		x = keyboard(KGETKEY, 0);		if (x != ' ') ret = -1;		break;	}  	wlocate(dialwin, 14, 6);  	wprintf(dialwin, "%2d ", f);  }#ifdef __linux__  /* MARK updated 02/17/94 - Min dial delay set to 0.35 sec instead of 1 sec */  if (f < 0) usleep(350000); /* Allow modem time to hangup if redial time == 0 */#else  if (f < 0) sleep(1);#endif  wlocate(dialwin, 1, 5);  wprintf(dialwin, "                              \n");  wprintf(dialwin, "                        ");  return(ret);}/* * Dial a number, and display the name. */int dial(d)struct dialent *d;{  char *s = 0, *t = 0;  int f, x = 0, nb, retst = -1;  int modidx, retries = 0;  int maxretries = 1, rdelay = 45;  char *reason = "Max retries";  time_t now, last;  char buf[128];  char modbuf[128];  dialwin = wopen(18, 9, 62, 15, BSINGLE, stdattr, mfcolor, mbcolor, 0, 0, 1);  wtitle(dialwin, TMID, "Autodial");  wcursor(dialwin, CNONE);  wputs(dialwin, "\n");  wprintf(dialwin, " Dialing : %s\n", d->name);  wprintf(dialwin, "      At : %s\n", d->number);  wredraw(dialwin, 1);  /* Tell keyboard routines we need them. */  keyboard(KSIGIO, 0);  maxretries = atoi(P_MRETRIES);  if (maxretries <= 0) maxretries = 1;  rdelay = atoi(P_MRDELAY);  if (rdelay < 0) rdelay = 0;  /* Main retry loop of dial() */MainLoop:  while(++retries <= maxretries) {	/* See if we need to try the next tagged entry. */	if (retries > 1 && (d->flags & FL_TAG)) {		do {			d = d->next;			if (d == (struct dialent *)NULL) d = dialents;		} while(!(d->flags & FL_TAG));		wlocate(dialwin, 0, 1);		wprintf(dialwin, " Dialing : %s", d->name);		wclreol(dialwin);		wprintf(dialwin, "\n      At : %s", d->number);		wclreol(dialwin);	}	/* Calculate dial time */	dialtime = atoi(P_MDIALTIME);	if (dialtime == 0) dialtime = 45;	time(&now);	last = now;  	/* Show used time */	wlocate(dialwin, 0, 3);	wprintf(dialwin, "    Time : %-3d", dialtime);	if (maxretries > 1) wprintf(dialwin, "     Attempt #%d", retries);	wputs(dialwin, "\n\n\n Escape to cancel, space to retry.");		/* Start the dial */	m_flush(portfd);	switch(d->dialtype) {		case 0:			mputs(P_MDIALPRE, 0);			mputs(d->number, 0);			mputs(P_MDIALSUF, 0);			break;		case 1:			mputs(P_MDIALPRE2, 0);			mputs(d->number, 0);			mputs(P_MDIALSUF2, 0);			break;		case 2:			mputs(P_MDIALPRE3, 0);			mputs(d->number, 0);			mputs(P_MDIALSUF3, 0);			break;	}	/* Wait 'till the modem says something */	modbuf[0] = 0;	modidx = 0;	s = buf;	buf[0] = 0;	while(dialtime > 0) {	    if (*s == 0) {		x = check_io(portfd, 0, 1000, buf, NULL);		s = buf;	    }	    if (x & 2) {		f = keyboard(KGETKEY, 0);		/* Cancel if escape was pressed. */		if (f == K_ESC) mputs(P_MDIALCAN, 0);		/* On space retry. */		if (f == ' ') {			mputs(P_MDIALCAN, 0);			dialfailed("Cancelled", 4);			m_flush(portfd);			break;		}		(void) keyboard(KSTOP, 0);		wclose(dialwin, 1);		return(retst);	    }	    if (x & 1) {		/* Data available from the modem. Put in buffer. */		if (*s == '\r' || *s == '\n') {			/* We look for [\r\n]STRING[\r\n] */			modbuf[modidx] = 0;			modidx = 0;		} else if (modidx < 127) {			/* Normal character. Add. */			modbuf[modidx++] = *s;			modbuf[modidx] = 0;		}		/* Skip to next received char */		if (*s) s++;		/* Only look when we got a whole line. */		if (modidx == 0 &&		    !strncmp(modbuf, P_MCONNECT, strlen(P_MCONNECT))) {			retst = 0;			/* Try to do auto-bauding */			if (sscanf(modbuf + strlen(P_MCONNECT), "%d", &nb) == 1)				retst = nb;			/* Try to figure out if this system supports DCD */			f = m_getdcd(portfd);			bogus_dcd = 1;			wlocate(dialwin, 1, 6);			if (d->script[0] == 0) {				wputs(dialwin,				     "Connected. Press any key to continue");#if VC_MUSIC				if (P_SOUND[0] == 'Y')					music();				else {					x = check_io(-1, 0, 0, NULL, NULL);					if ((x & 2) == 2)						(void) keyboard(KGETKEY, 0);				}#else				/* MARK updated 02/17/94 - If VC_MUSIC is not */				/* defined, then at least make some beeps! */				if (P_SOUND[0] == 'Y') 					wputs(dialwin,"\007\007\007");#endif				x = check_io(-1, 0, 0, NULL, NULL);				if ((x & 2) == 2)					(void) keyboard(KGETKEY, 0);			}			keyboard(KSTOP, 0);			wclose(dialwin, 1);			/* Print out the connect strings. */			wprintf(us, "\r\n%s\r\n", modbuf);			dialwin = NIL_WIN;			/* Un-tag this entry. */			d->flags &= ~FL_TAG;			return(retst);		}		for(f = 0; f < 3; f++) {			if (f == 0) t = P_MNOCON1;			if (f == 1) t = P_MNOCON2;			if (f == 2) t = P_MNOCON3;			if (f == 3) t = P_MNOCON4;			if ((*t) && (!strncmp(modbuf, t, strlen(t)))) {				if (retries < maxretries) {					x = dialfailed(t, rdelay);					if (x < 0) {						keyboard(KSTOP, 0);						wclose(dialwin, 1);						return(retst);					}				}				if (maxretries == 1) reason = t;				goto MainLoop;			}		}	    }	    /* Do timer routines here. */	    time(&now);	    if (last != now) {		dialtime -= (now - last);		if (dialtime < 0) dialtime = 0;		wlocate(dialwin, 11, 3);		wprintf(dialwin, "%-3d  ", dialtime);		if (dialtime <= 0) {			mputs(P_MDIALCAN, 0);			reason = "Timeout";			retst = -1;			if (retries < maxretries) {				x = dialfailed(reason, rdelay);				if (x < 0) {					keyboard(KSTOP, 0);					wclose(dialwin, 1);					return(retst);				}			}		}	    }	    last = now;	}  } /* End of main while cq MainLoop */	  dialfailed(reason, -1);  keyboard(KSTOP, 0);  wclose(dialwin, 1);  return(retst);}/* * Create an empty entry. */static struct dialent *mkstdent(){  struct dialent *d;    d = (struct dialent *)malloc(sizeof (struct dialent));    if (d == (struct dialent *)0) return(d);  d->name[0] = 0;  d->number[0] = 0;  d->script[0] = 0;  d->username[0] = 0;  d->password[0] = 0;  d->term = 1;  d->dialtype = 0;  d->flags = FL_DEL;  strcpy(d->baud, "Curr");  strcpy(d->bits, "8");  strcpy(d->parity, "N");  d->next = (struct dialent *)0;  return(d);}/* Read version 3 of the dialing directory. */void v3_read(fp, d)struct dialent *d;FILE *fp;{  (void) fread((char *)d, sizeof(struct dialent), (size_t)1, fp);}/* Read version 2 of the dialing directory. */void v2_read(fp, d)struct dialent *d;FILE *fp;{  (void) fread((char *)d, sizeof(struct dialent), (size_t)1, fp);  if (d->flags & FL_ANSI) d->flags |= FL_WRAP;}/* Read version 1 of the dialing directory. */void v1_read(fp, d)FILE *fp;struct dialent *d;{  struct v1_dialent v1;  fread((char *)&v1, sizeof(v1), (size_t)1, fp);  memcpy(d->username, v1.username, sizeof(v1) - offsetof(struct v1_dialent, username));  strcpy(d->name, v1.name);  strcpy(d->number, v1.number);  strcpy(d->script, v1.script);}/* Read version 0 of the dialing directory. */void v0_read(fp, d)FILE *fp;struct dialent *d;{  v1_read(fp, d);  d->dialtype = 0;  d->flags = 0;}/* * Read in the dialing directory from $HOME/.dialdir */int readdialdir(){  long size;  FILE *fp;  char dfile[256];  static int didread = 0;  int f;  struct dialent *d = NULL, *prev = (struct dialent *)0;  struct dver dial_ver;  if (didread) return(0);  didread = 1;  nrents = 1;  tagged = (char *)malloc(1);  tagged[0] = 0;  /* Make the manual dial entry. */  d_man = mkstdent();  strcpy(d_man->name, "Manually entered number");  /* Construct path */  sprintf(dfile, "%s/.dialdir", homedir);  /* Try to open ~/.dialdir */  if ((fp = sfopen(dfile, "r")) == (FILE *)NULL) {	if (errno == EPERM) {		werror("Cannot open ~/.dialdir: permission denied");		dialents = mkstdent();		dendd = 1;		return(0);	}  	dialents = mkstdent();  	return(0);  }  /* Get size of the file */  fseek(fp, 0L, SEEK_END);  size = ftell(fp);  if (size == 0) {  	dialents = mkstdent();  	fclose(fp);  	return(0);  }  /* Get version of the dialing directory */  fseek(fp, 0L, SEEK_SET);  fread(&dial_ver, sizeof(dial_ver), 1, fp);  if (dial_ver.magic != DIALMAGIC) {	/* First version without version info. */	dial_ver.version = 0;	fseek(fp, 0L, SEEK_SET);  } else	size -= sizeof(dial_ver);  /* See if the size of the file is allright. */  switch(dial_ver.version) {	case 0:	case 1:		dial_ver.size = sizeof(struct v1_dialent);		break;	case 2:	case 3:		dial_ver.size = sizeof(struct dialent);		break;	default:  		werror("Unknown dialing directory version");		dendd = 1;  		dialents = mkstdent();  		return(-1);  }  if (size % dial_ver.size != 0) {  	werror("Phonelist garbled (?)");  	fclose(fp);#if 0 /* This should be less facistic now. */  	unlink(dfile);#else	dendd = 1;#endif  	dialents = mkstdent();  	return(-1);  }  /* Read in the dialing entries */  nrents = size / dial_ver.size;  if (nrents == 0) {	dialents = mkstdent();

⌨️ 快捷键说明

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