📄 dial.c
字号:
/* * 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. * * jl 22.06.97 Logging connects and disconnects. * jl 23.06.97 Adjustable DTR droptime * jl 21.09.97 Conversion table filenames in dialdir * jl 05.10.97 Line speed changed to long in dial() * jl 26.01.98 last login date & time added to dialing window * jl 16.04.98 start searching for dialing tags from the highlighted entry * jl 12.06.98 save the old dialdir if it was an old version * er 18-Apr-99 When calling a multiline BBS * tagged entries with same name are untagged * jl 01.09.99 Move entry up/down in directory * jl 10.02.2000 Stopbits field added */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "rcsid.h"RCSID("$Id: dial.c,v 1.21 2005/10/31 12:13:51 al-guest Exp $")#include "port.h"#include "minicom.h"#include "intl.h"#ifdef VC_MUSIC# if defined(__GLIBC__)# include <sys/ioctl.h># include <sys/kd.h># include <sys/time.h># endif# if defined(_COH42) || defined(_SCO)# include <sys/vtkd.h># endif#endif/* 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 v3_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;};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]; char lastdate[9]; /* jl 22.06.97 */ char lasttime[9]; /* jl 22.06.97 */ int count; /* jl 22.06.97 */ char convfile[16]; /* jl 21.09.97 */ char stopb[2]; /* jl 10.02.2000 */ struct dialent *next;};/* Version info. */#define DIALMAGIC 0x55AAstruct dver { short magic; short version; unsigned short size; short res1; short res2; short res3; short res4;};/* Forward declaration */static void writedialdir(void);#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;char *dial_user;char *dial_pass;/* Change the baud rate. Treat all characters in the given array as if * they were key presses within the comm parameters dialog (C-A P) and * change the line speed accordingly. Terminate when a space or other * unrecognised character is found. */const char* change_baud(const char *s){ int max = m_getmaxspd(); while (s && *s && update_bbp_from_char(*s, P_BAUDRATE, P_BITS, P_PARITY, P_STOPB, 0, max)) ++s; // reinitialise the port and update the status line if (portfd >= 0) port_init(); if (st) mode_status(); return s;}/* * 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(const 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 if (*s == '\\' && (*(s + 1))) { s++; switch (toupper (*s)) { case '\\': c = *s; break; case 'U': if (dial_user && *dial_user) mputs (dial_user, how); s++; continue; case 'P': if (dial_pass && *dial_pass) mputs (dial_pass, how); s++; continue; case 'B': /* line speed change. */ s = change_baud(++s); continue; case 'L': /* toggle linefeed addition */ toggle_addlf(); s++; /* nothing to do with the modem, move along */ continue; case 'E': /* toggle local echo */ toggle_local_echo(); s++; /* again, move along. */ continue; default: s++; continue; } } else c = *s; if (how == 0 && c == '~') sleep(1); else write(portfd, &c, 1); s++; }}/* * Initialize the modem. */void modeminit(void){ WIN *w; if (P_MINIT[0] == '\0') return; w = mc_tell(_("Initializing Modem")); m_dtrtoggle(portfd, 1); /* jl 23.06.97 */ mputs(P_MINIT, 0); wclose(w, 1);}/* * Reset the modem. */void modemreset(void){ WIN *w; if (P_MRESET[0] == '\0') return; w = mc_tell(_("Resetting Modem")); mputs(P_MRESET, 0); sleep(1); wclose(w, 1);}/* * Hang the line up. */void hangup(void){ WIN *w; int sec=1; w = mc_tell(_("Hanging up")); timer_update(); if (P_LOGCONN[0] == 'Y') do_log(_("Hangup (%ld:%02ld:%02ld)"), online / 3600, (online / 60) % 60, online>0 ? online % 60 : 0); online = -1; old_online = -1; if (isdigit(P_MDROPDTR[0])) sscanf(P_MDROPDTR,"%2d",&sec); if (P_MDROPDTR[0] == 'Y' || (isdigit(P_MDROPDTR[0]) && sec>0)) { m_dtrtoggle(portfd, sec); /* jl 23.06.97 */ } else { mputs(P_MHANGUP, 0); sleep(1); }#ifdef _DCDFLOW /* DCD has dropped, turn off hw flow control. */ m_sethwf(portfd, 0);#endif /* If we don't have DCD support fake DCD dropped */ bogus_dcd = 0; wclose(w, 1); if (st) time_status();}/* * This seemed to fit best in this file * Send a break signal. */void sendbreak(){ WIN *w; w = mc_tell(_("Sending BREAK")); wcursor(w, CNONE); m_break(portfd); wclose(w, 1);} WIN *dialwin;int dialtime;#ifdef VC_MUSIC/* * Play music until key is pressed. */void music(void){ 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); ioctl(consolefd, KIOCSOUND, k); /* Check keypress with timeout 160 ms */ x = check_io(-1, 0, 160, NULL, NULL); if (x & 2) break; } 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); timer_update(); } keyboard(KGETKEY, 0);}#endif/* * The dial has failed. Tell user. * Count down until retrytime and return. */static int dialfailed(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) 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, 0, 6); wprintf(dialwin, _(" Retry in %2d seconds "), f); }#ifdef HAVE_USLEEP /* MARK updated 02/17/94 - Min dial delay set to 0.35 sec instead of 1 sec */ if (f < 0) /* Allow modem time to hangup if redial time == 0 */ usleep(350000);#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. */long dial(struct dialent *d, struct dialent **d2){ char *s = 0, *t = 0; int f, x = 0; int modidx, retries = 0; int maxretries = 1, rdelay = 45; long nb, retst = -1; char *reason = _("Max retries"); time_t now, last; struct tm *ptime; char buf[128]; char modbuf[128]; /* char logline[128]; */ timer_update(); /* Statusline may still show 'Online' / jl 16.08.97 */ /* don't do anything if already online! jl 07.07.98 */ if (P_HASDCD[0]=='Y' && online >= 0) { werror(_("You are already online! Hang up first.")); return(retst); } dialwin = wopen(18, 9, 62, 16, BSINGLE, stdattr, mfcolor, mbcolor, 0, 0, 1); wtitle(dialwin, TMID, _("Autodial")); wcursor(dialwin, CNONE); wputs(dialwin, "\n"); wprintf(dialwin, " %s : %s\n", _("Dialing"), d->name); wprintf(dialwin, _(" At : %s"), d->number); wprintf(dialwin, "\n"); /* help translators */ if (d->lastdate[0] && d->lasttime[0]) /* jl 26.01.98 */ wprintf(dialwin, _(" Last on : %s at %s"), d->lastdate, d->lasttime); wprintf(dialwin, "\n"); 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, " %s : %s", _("Dialing"), d->name); wclreol(dialwin); wprintf(dialwin, "\n"); /* helps translators */ wprintf(dialwin, _(" At : %s"), d->number); wclreol(dialwin); if (d->lastdate[0] && d->lasttime[0]) { wprintf(dialwin, "\n"); /* don't merge with next printf, helps translators */ wprintf(dialwin, _(" Last on : %s at %s"), d->lastdate, d->lasttime); wclreol(dialwin); } } /* Calculate dial time */ dialtime = atoi(P_MDIALTIME); if (dialtime == 0) dialtime = 45; time(&now); last = now; /* Show used time */ wlocate(dialwin, 0, 4); 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_connected, 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; } 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))) { timer_update(); /* the login scipt may take long.. */ retst = 0; /* Try to do auto-bauding */ if (sscanf(modbuf + strlen(P_MCONNECT), "%ld", &nb) == 1) retst = nb; linespd = retst; /* Try to figure out if this system supports DCD */ f = m_getdcd(portfd); bogus_dcd = 1; /* jl 22.05.97, 22.09.97, 05.04.99 */ if (P_LOGCONN[0] == 'Y') do_log("%s %s, %s",modbuf, d->name, d->number); ptime = localtime(&now); sprintf(d->lastdate,"%4.4d%2.2d%2.2d", (ptime->tm_year)+1900,(ptime->tm_mon)+1, ptime->tm_mday); sprintf(d->lasttime,"%02d:%02d", ptime->tm_hour,ptime->tm_min); d->count++; if (d->convfile[0]) { loadconv(d->convfile); /* jl 21.09.97 */ strcpy(P_CONVF, d->convfile); } wlocate(dialwin, 1, 7); if (d->script[0] == 0) { wputs(dialwin, _("Connected. Press any key to continue"));#ifdef VC_MUSIC if (P_SOUND[0] == 'Y') music(); else { x = check_io(-1, 0, 0, NULL, NULL); if ((x & 2) == 2) 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) keyboard(KGETKEY, 0); } keyboard(KSTOP, 0); wclose(dialwin, 1); /* Print out the connect strings. */ wprintf(us, "\r\n%s\r\n", modbuf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -