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

📄 updown.c

📁 minicom源碼,用於Linux下Terminal的重要程序
💻 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. * * jl 13.09.97	pass actual terminal lines (LINES - statusline) *		to runscript in environment variable TERMLIN * jl 16.09.97	logging of sz/rz file transfers * jl 29.09.97	fix on the transfer logging * hgk&jl 2.98	filename selection window * acme 25.02.98 i18n * js&jl 04.98	the better filename selection window */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "rcsid.h"RCSID("$Id: updown.c,v 1.1.1.1 2003/03/30 18:55:54 al-guest Exp $")#include "port.h"#include "minicom.h"#include "intl.h"/*#define LOG_XFER	  debugging option to log all output of rz/sz */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 != '/') {  	snprintf(buf, sizeof(buf), "%s/%s", homedir, dir);  	dir = buf;  }  if (chdir(dir) < 0) {  	/* This may look safe but you might I8N change the string! so  	   snprintf it */  	snprintf(err, sizeof(err),  _("Cannot chdir to %.30s"), dir);  	werror("%s", 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 bps rate, and *           %l to the current tty port. *           %f to the serial port file descriptor */static char *translate(s)char *s;{  static char buf[128];  char str_portfd[8];     /* kino */  int i;  for(i = 0; *s && i < 127; i++, s++) {  	if (*s != '%') {  		buf[i] = *s;  		continue;  	}  	switch(*++s) {  		case 'l':  			strncpy(buf + i, dial_tty, sizeof(buf)-i);  			i += strlen(dial_tty) - 1;  			break;  		case 'b':  			strncpy(buf + i, P_BAUDRATE, sizeof(buf)-i);  			i += strlen(P_BAUDRATE) - 1;  			break; 		case 'f':		  	sprintf(str_portfd, "%d", portfd);                        strncpy(buf + i, str_portfd, sizeof(buf)-i);                        i += strlen(str_portfd) - 1;                        break;  		default:  			buf[i++] = '%';  			buf[i] = *s;  			break;  	}  }  buf[i] = 0;  return(buf);}/* * Trim the leading & trailing whitespaces from the string * jl 15.09.97 */char *trim(char *outstring, char *instring, int n){  char *p;  char *ip;  char *op;  char *np;  ip = instring;  np = ip + n;  while ((*ip <= ' ') && (ip < np)) ip++;  op = outstring;  np = op + n;  while ((*ip >= ' ') && (op <= np)) {    *op = *ip;    ip++;    op++;  }  if (op<np)    *op = 0;  while ((op > outstring) && (*op <= ' ')) {    *op = 0;    op--;  }  p = outstring;  return(p);}  /* * Choose from numerous up and download protocols! */void updown(what, nr)int what;int nr;{#ifdef LOG_XFER  #warning LOG_XFER defined!  FILE *xfl;#endif  char *name[13];  int idx[13];  int r, f, g = 0;  char *t = what == 'U' ? _("Upload") : _("Download");  char buf[160];  char buffirst[20];  char xfrstr[160] = "";  char trimbuf[160] = "";  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;/* jseymour file selector with choice of dir on zmodem, etc. download */#if 1  {	int multiple; /* 0:only directory, 1:one file, -1:any number */		if(P_MUL(g)=='Y') {	    /* need file(s), or just a directory? */	    multiple = what == 'U'? -1 : 0;	}	else {	    multiple = 1;	/* only one allowed */	}	if (P_FSELW[0] == 'Y' && (what == 'U' || P_ASKDNDIR[0] == 'Y')) {	  s = filedir(multiple, what == 'U'? 0 : 1);	  if (s == NULL)	    return;	}	else if (P_PNN(g) == 'Y') {	  s = input(_("Please enter file names"), buf);	  if (s == NULL)	    return;	}	/* discard directory if "multiple" == 0 */	snprintf(cmdline, sizeof(cmdline), "%s %s", P_PPROG(g), multiple == 0? "" : s);  }#endif  if (P_LOGXFER[0] == 'Y')    do_log("%s", cmdline);   /* jl 22.06.97 */  if (P_PFULL(g) == 'N') {    win = wopen(10, 7, 70, 13, BSINGLE, stdattr, mfcolor, mbcolor, 1, 0, 1);    snprintf(title, sizeof(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]);#ifdef LOG_XFER	xfl=fopen("xfer.log","wb");#endif	while((n = read(pipefd[0], buf, sizeof(buf))) > 0) {	  	buf[n] = '\0';  		wputs(win, buf);		timer_update();		/* Log the filenames & sizes 	jl 14.09.97 */		if (P_LOGXFER[0] == 'Y') {#ifdef LOG_XFER		  if (xfl)		    fprintf(xfl,">%s<\n",buf);#endif		  if (sscanf(buf, "%19s", buffirst)) { /* if / jl 29.09.97 */		    if (!strncmp (buffirst, "Receiving", 9) ||			!strncmp (buffirst, "Sending", 7)) {		      if (xfrstr[0]) {			trim (trimbuf, xfrstr, sizeof(trimbuf));			do_log ("%s", trimbuf);			xfrstr[0] = 0;		      }		      trim (trimbuf, buf, sizeof(trimbuf));		      do_log("%s", trimbuf);		    } else if (!strncmp (buffirst, "Bytes", 5)) {		      strncpy (xfrstr, buf, sizeof(xfrstr));		    }		    buffirst[0]=0;		    trimbuf[0]=0;		  }		}	}#ifdef LOG_XFER	if (xfl)	  fclose(xfl);#endif  }  /* Log the last file size	jl 14.09.97 */  if (P_LOGXFER[0] == 'Y' && xfrstr[0]) {    trim (trimbuf, xfrstr, sizeof(trimbuf));    do_log ("%s", trimbuf);    xfrstr[0] = 0;  }  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. */  if (win) close(pipefd[0]);  (void) mcd("");  timer_update();  /* 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);  		snprintf(buf, sizeof(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(p, *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 scr_lines[5];  char cmdline[128];  char *ptr;  WIN *w;  int done = 0;  char *msg = _("Same as last");  char* username = _(" A -   Username        :"),      * password = _(" B -   Password        :"),      * name_of_script = _(" C -   Name of script  :"),      * question = _("Change which setting?     (Return to run, ESC to stop)");  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, "%s %s\n", username, scr_user[0] ? msg : "");	wprintf(w, "%s %s\n", password, scr_passwd[0] ? msg : "");	wprintf(w, "%s %s\n", name_of_script, scr_name);	wlocate(w, 4, 5);	wputs(w, question);	wredraw(w, 1);	while(!done) {	    wlocate(w, strlen (question) + 5, 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, strlen (username) + 1, 1);			wclreol(w);			scr_user[0] = 0;			wgets(w, scr_user, 32, 32);			break;		case 'B':			wlocate(w, strlen (password) + 1, 2);			wclreol(w);			scr_passwd[0] = 0;			wgets(w, scr_passwd, 32, 32);			break;		case 'C':			wlocate(w, strlen (name_of_script) + 1, 3);			wgets(w, scr_name, 32, 32);			break;		default:			break;	    }	}  } else {  	strncpy(scr_user, l, sizeof(scr_user));  	strncpy(scr_name, s, sizeof(scr_name));  	strncpy(scr_passwd, p, sizeof(scr_passwd));  }  sprintf(scr_lines, "%d", (int) lines);  /* jl 13.09.97 */  /* 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;  snprintf(cmdline, sizeof(cmdline), "%s %s %s %s",	   P_SCRIPTPROG, scr_name, logfname, logfname[0]==0? "": homedir);  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);		mc_setenv("TERMLIN", scr_lines);	/* jl 13.09.97 */  		(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 + -