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

📄 updown.c

📁 VT100终端程序
💻 C
字号:
/* * updown.c	Routines to do up and downloading by calling external *		programs (sz, rz, kermit). * *		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"static int udpid;/* * Change to a directory. */static int mcd(dir)char *dir;{  char buf[256];  char err[50];  static char odir[256];  static int init = 0;  if (!init) {  	if (*dir == 0) return(0);  	init = 1;#if defined (_COH3) || defined(NeXT)	getwd(odir);#else  	getcwd(odir, 255);#endif  }  if (*dir == 0) {  	chdir(odir);  	return(0);  }    if(*dir != '/') {  	sprintf(buf, "%s/%s", homedir, dir);  	dir = buf;  }  if (chdir(dir) < 0) {  	sprintf(err, "Cannot chdir to %.30s", dir);  	werror(err);  	return(-1);  }  return(0);}/* * Catch the CTRL-C signal. *//*ARGSUSED*/static void udcatch(dummy)int dummy;{  (void)dummy;  signal(SIGINT, udcatch);  if (udpid) kill((pid_t)udpid, SIGKILL);}/* * Translate %b to the current baudrate, and *           %l to the current tty port. */static char *translate(s)char *s;{  static char buf[128];  int i;  for(i = 0; *s && i < 127; i++, s++) {  	if (*s != '%') {  		buf[i] = *s;  		continue;  	}  	switch(*++s) {  		case 'l':  			strcpy(buf + i, dial_tty);  			i += strlen(dial_tty) - 1;  			break;  		case 'b':  			strcpy(buf + i, P_BAUDRATE);  			i += strlen(P_BAUDRATE) - 1;  			break;  		default:  			buf[i++] = '%';  			buf[i] = *s;  			break;  	}  }  buf[i] = 0;  return(buf);}/* * Choose from numerous up and download protocols! */void updown(what, nr)int what;int nr;{  char *name[13];  int idx[13];  int r, f, g = 0;  char *t = what == 'U' ? "Upload" : "Download";  char buf[128];  char title[64];  char *s ="";  int pipefd[2];  int n, status;  char cmdline[128];  WIN *win = (WIN *)NULL;#if VC_MUSIC  _PROTO(void music, (void));#endif  if (mcd(what == 'U' ? P_UPDIR : P_DOWNDIR) < 0)  	return;  /* Automatic? */  if (nr == 0) {	for(f = 0; f < 12; f++) {  		if (P_PNAME(f)[0] && P_PUD(f) == what) {  			name[g] = P_PNAME(f);  			idx[g++] = f;  		}	}	name[g] = CNULL;	if (g == 0) return;	r = wselect(30, 7, name, NIL_FUNLIST, t, stdattr, mfcolor, mbcolor) - 1;	if (r < 0) return;	g = idx[r];  } else g = nr;  buf[0] = 0;  if (P_PNN(g) == 'Y') {  	s = input("Please enter file names", buf);  	if (s == CNULL || *s == 0) return;  }  sprintf(cmdline, "%s %s", P_PPROG(g), s);  if (P_PFULL(g) == 'N') {	win = wopen(10, 7, 70, 13, BSINGLE, stdattr, mfcolor, mbcolor, 1, 0, 1);	sprintf(title, "%.30s %s - Press CTRL-C to quit", P_PNAME(g),		what == 'U' ? "upload" : "download");	wtitle(win, TMID, title);	pipe(pipefd);  } else	wleave();  switch(udpid = fork()) {  	case -1:  		werror("Out of memory: could not fork()");		if (win) {  			close(pipefd[0]);  			close(pipefd[1]);	  		wclose(win, 1);		} else			wreturn();  		(void) mcd("");  		return;  	case 0: /* Child */		if (P_PIORED(g) == 'Y') {  			dup2(portfd, 0);  			dup2(portfd, 1);		}		if (win) {  			dup2(pipefd[1], 2);  			close(pipefd[0]);  			if (pipefd[1] != 2) close(pipefd[1]);  		}  		for(n = 1; n < _NSIG; n++) signal(n, SIG_DFL);  				set_privs();		setgid((gid_t)real_gid);  		setuid((uid_t)real_uid);  		(void) fastexec(translate(cmdline));  		exit(1);  	default: /* Parent */  		break;  }  if (win) {	(void) setcbreak(1); /* Cbreak, no echo. */	enab_sig(1, 0);	       /* But enable SIGINT */  }  signal(SIGINT, udcatch);  if (P_PIORED(g) == 'Y') {	close(pipefd[1]);	while((n = read(pipefd[0], buf, 80)) > 0) {	  	buf[n] = '\0';  		wputs(win, buf);		timer_update();	}  }  while( udpid != m_wait(&status) );  if (win) {	enab_sig(0, 0);	signal(SIGINT, SIG_IGN);  }  if (win == (WIN *)0) wreturn();  /* MARK updated 02/17/94 - Flush modem port before displaying READY msg */  /* because a BBS often displays menu text right after a download, and we */  /* don't want the modem buffer to be lost while waiting for key to be hit */  m_flush(portfd);  port_init();  (void) setcbreak(2); /* Raw, no echo. */  close(pipefd[0]);  (void) mcd("");  /* If we got interrupted, status != 0 */  if (win && (status & 0xFF00) == 0) {#if VC_MUSIC	if (P_SOUND[0] == 'Y') {		wprintf(win, "\n READY: press any key to continue...");		music();	} else		sleep(1);#else	/* MARK updated 02/17/94 - If there was no VC_MUSIC capability, */	/* then at least make some beeps! */	if (P_SOUND[0] == 'Y') wprintf(win, "\007\007\007");	sleep(1);#endif  }  if (win) wclose(win, 1);}/* * Run kermit. Used to do this in the main window, but newer * versions of kermit are too intelligent and just want a tty * for themselves or they won't function ok. Shame. */void kermit(){  int status;  int pid, n;  char buf[81];  int fd;  /* Clear screen, set keyboard modes etc. */  wleave();  switch(pid = fork()) {  	case -1:		wreturn();  		werror("Out of memory: could not fork()");  		return;  	case 0: /* Child */  		/* Remove lockfile */		set_privs();  		if (lockfile[0]) unlink(lockfile);		setgid((gid_t)real_gid);		setuid((uid_t)real_uid);  		for(n = 0; n < _NSIG; n++) signal(n, SIG_DFL);  		(void) fastexec(translate(P_KERMIT));  		exit(1);  	default: /* Parent */  		break;  }  (void) m_wait(&status);  /* Restore screen and keyboard modes */  wreturn();  /* Re-create lockfile */  if (lockfile[0]) {	set_privs();	n = umask(022);  	/* Create lockfile compatible with UUCP-1.2 */  	if ((fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, 0666)) < 0) {  		werror("Cannot re-create lockfile!");  	} else {		(void) chown(lockfile, (uid_t)real_uid, (gid_t)real_gid);  		sprintf(buf, "%05d minicom %.20s\n", (int)getpid(), username);  		write(fd, buf, strlen(buf));  		close(fd);  	}	(void) umask(n);	drop_privs();  }  m_flush(portfd);  port_init();}/* ============ Here begins the setenv function ============= *//* * Compare two strings up to '=' */static int varcmp(s1, s2)char *s1, *s2;{  while(*s1 && *s2) {  	if (*s1 == '=' && *s2 == '=') return(1);  	if (*s1++ != *s2++) return(0);  }  return(1);}/* * Generate a name=value string. */static char *makenv(name, value)char *name, *value;{  char *p;    if ((p = (char *)malloc(strlen(name) + strlen(value) + 3)) == CNULL)	return(p);  sprintf(p, "%s=%s", name, value);  return(p);}/* * Set a environment variable.  */int mc_setenv(name, value)char *name, *value;{  static int init = 0;  extern char **environ;  char *p, **e, **newe;  int count = 0;  if ((p = makenv(name, value)) == CNULL) return(-1);  for(e = environ; *e; e++) {  	count++;  	if(varcmp(name, *e)) {  		*e = p;  		return(0);  	}  }  count += 2;  if ((newe = (char **)malloc(sizeof(char *) * count)) == (char **)0) {  	free(p);  	return(-1);  }  memcpy((char *)newe, (char *)environ , (int) (count * sizeof(char *)));  if (init) free((char *)environ);  init = 1;  environ = newe;  for(e = environ; *e; e++)  	;  *e++ = p;  *e = CNULL;  return(0);}/* ============ This is the end of the setenv function ============= *//* * Run an external script. * ask = 1 if first ask for confirmation. * s = scriptname, l=loginname, p=password. */void runscript(ask, s, l, p)int ask;char *s, *l, *p;{  int status;  int n;  int pipefd[2];  char buf[81];  char cmdline[128];  char *ptr;  WIN *w;  int done = 0;  char *msg = "Same as last";  if (ask) {	w = wopen(10, 5, 70, 10, BDOUBLE, stdattr, mfcolor, mbcolor, 0, 0, 1);	wtitle(w, TMID, "Run a script");	wputs(w, "\n");	wprintf(w, " A -   Username        : %s\n",					scr_user[0] ? msg : "");	wprintf(w, " B -   Password        : %s\n",					scr_passwd[0] ? msg : "");	wprintf(w, " C -   Name of script  : %s\n", scr_name);	wlocate(w, 4, 5);	wputs(w, "Change which setting?     (Return to run, ESC to stop)");	wredraw(w, 1);	while(!done) {	    wlocate(w, 26, 5);	    n = wxgetch();	    if (islower(n)) n = toupper(n);	    switch(n) {		case '\r':		case '\n':			if (scr_name[0] == '\0') {				wbell();				break;			}			wclose(w, 1);			done = 1;			break;		case 27: /* ESC */			wclose(w, 1);			return;		case 'A':			wlocate(w, 25, 1);			wclreol(w);			scr_user[0] = 0;			wgets(w, scr_user, 32, 32);			break;		case 'B':			wlocate(w, 25, 2);			wclreol(w);			scr_passwd[0] = 0;			wgets(w, scr_passwd, 32, 32);			break;		case 'C':			wlocate(w, 25, 3);			wgets(w, scr_name, 32, 32);			break;		default:			break;	    }	}  } else {  	strcpy(scr_user, l);  	strcpy(scr_name, s);  	strcpy(scr_passwd, p);  }  /* Throw away status line if temporary */  if (tempst) {  	wclose(st, 1);  	tempst = 0;  	st = NIL_WIN;  }  scriptname(scr_name);    pipe(pipefd);  if (mcd(P_SCRIPTDIR) < 0) return;  sprintf(cmdline, "%s %s", P_SCRIPTPROG, scr_name);  switch(udpid = fork()) {  	case -1:  		werror("Out of memory: could not fork()");  		close(pipefd[0]);  		close(pipefd[1]);  		(void) mcd("");  		return;  	case 0: /* Child */  		dup2(portfd, 0);  		dup2(portfd, 1);  		dup2(pipefd[1], 2);  		close(pipefd[0]);  		close(pipefd[1]);  		  		for(n = 1; n < _NSIG; n++) signal(n, SIG_DFL);  				set_privs();		setgid((gid_t)real_gid);  		setuid((uid_t)real_uid);  		mc_setenv("LOGIN", scr_user);  		mc_setenv("PASS", scr_passwd);  		(void) fastexec(translate(cmdline));  		exit(1);  	default: /* Parent */  		break;  }  (void) setcbreak(1); /* Cbreak, no echo */  enab_sig(1, 0);	       /* But enable SIGINT */  signal(SIGINT, udcatch);  close(pipefd[1]);    /* pipe output from "runscript" program to terminal emulator */  while((n = read(pipefd[0], buf, 80)) > 0) {  	ptr = buf;  	while(n--)  		vt_out(*ptr++);	timer_update();  	wflush();  }    /* Collect status, and clean up. */  (void) m_wait(&status);  enab_sig(0, 0);  signal(SIGINT, SIG_IGN);  (void) setcbreak(2); /* Raw, no echo */  close(pipefd[0]);  scriptname("");  (void) mcd("");}

⌨️ 快捷键说明

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