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

📄 main.c

📁 unix下tftp服务器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	$OpenBSD: main.c,v 1.4 1997/01/17 07:13:30 millert Exp $	*//*	$NetBSD: main.c,v 1.6 1995/05/21 16:54:10 mycroft Exp $	*//* * Copyright (c) 1983, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include "tftpsubs.h"#ifndef lintstatic const char *copyright UNUSED ="@(#) Copyright (c) 1983, 1993\n\	The Regents of the University of California.  All rights reserved.\n";/* static char sccsid[] = "@(#)main.c	8.1 (Berkeley) 6/6/93"; *//* static char rcsid[] = "$OpenBSD: main.c,v 1.4 1997/01/17 07:13:30 millert Exp $"; */static const char *rcsid UNUSED = "tftp-hpa $Id: main.c,v 1.21 2004/01/08 20:47:00 hpa Exp $";#endif /* not lint *//* Many bug fixes are from Jim Guyton <guyton@rand-unix> *//* * TFTP User Program -- Command Interface. */#include <sys/file.h>#include <ctype.h>#include <netdb.h>#ifdef WITH_READLINE#include <readline/readline.h>#ifdef HAVE_READLINE_HISTORY_H#include <readline/history.h>#endif#endif#include "extern.h"#define	TIMEOUT		5		/* secs between rexmt's */#define	LBUFLEN		200		/* size of input buffer */struct modes {  const char *m_name;  const char *m_mode;  int m_openflags;};static const struct modes modes[] = {	{ "netascii", "netascii", O_TEXT },	{ "ascii",    "netascii", O_TEXT },	{ "octet",    "octet",    O_BINARY },	{ "binary",   "octet",    O_BINARY },	{ "image",    "octet",    O_BINARY },	{ 0, 0, 0 }};#define MODE_OCTET    (&modes[2])#define MODE_NETASCII (&modes[0])#define MODE_DEFAULT  MODE_NETASCIIstruct	sockaddr_in peeraddr;int	f;u_short port;int	trace;int	verbose;int	connected;const struct modes *mode;#ifdef WITH_READLINEchar   *line = NULL;#elsechar	line[LBUFLEN];#endifint	margc;char	*margv[20];const char *prompt = "tftp> ";sigjmp_buf	toplevel;void	intr(int);struct	servent *sp;void	get (int, char **);void	help (int, char **);void	modecmd (int, char **);void	put (int, char **);void	quit (int, char **);void	setascii (int, char **);void	setbinary (int, char **);void	setpeer (int, char **);void	setrexmt (int, char **);void	settimeout (int, char **);void	settrace (int, char **);void	setverbose (int, char **);void	status (int, char **);static void command (void);static void getusage (char *);static void makeargv (void);static void putusage (char *);static void settftpmode (const struct modes *);#define HELPINDENT (sizeof("connect"))struct cmd {	const char *name;	const char *help;	void	(*handler) (int, char **);};struct cmd cmdtab[] = {  { "connect",    "connect to remote tftp",    setpeer },  { "mode",    "set file transfer mode",    modecmd },  { "put",    "send file",    put },  { "get",    "receive file",    get },  { "quit",    "exit tftp",    quit },  { "verbose",    "toggle verbose mode",    setverbose },  { "trace",    "toggle packet tracing",    settrace },  { "status",    "show current status",    status },  { "binary",    "set mode to octet",    setbinary },  { "ascii",    "set mode to netascii",    setascii },  { "rexmt",    "set per-packet transmission timeout",    setrexmt },  { "timeout",    "set total retransmission timeout",    settimeout },  { "?",    "print help information",    help },  { "help",    "print help information",    help },  { 0, 0, 0 }};struct	cmd *getcmd(char *);char	*tail(char *);char *xstrdup(const char *);const char *program;static inline void usage(int errcode){  fprintf(stderr, "Usage: %s [-v][-m mode] [host [port]] [-c command]\n", program);  exit(errcode);}intmain(int argc, char *argv[]){  struct sockaddr_in s_in;  int arg;  static int pargc, peerargc;  static int iscmd = 0;  char **pargv;  const char *optx;  char *peerargv[3];  program = argv[0];  mode = MODE_DEFAULT;  peerargv[0] = argv[0];  peerargc = 1;  for ( arg = 1 ; !iscmd && arg < argc ; arg++ ) {    if ( argv[arg][0] == '-' ) {      for ( optx = &argv[arg][1] ; *optx ; optx++ ) {	switch ( *optx ) {	case 'v':	  verbose = 1;	  break;	case 'V':	  /* Print version and configuration to stdout and exit */	  printf("%s\n", TFTP_CONFIG_STR);	  exit(0);	case 'm':	  if ( ++arg >= argc )	    usage(EX_USAGE);	  {	    const struct modes *p;	    	    for ( p = modes ; p->m_name ; p++ ) {	      if (!strcmp(argv[arg], p->m_name))		break;	    }	    if (p->m_name) {	      settftpmode(p);	    } else {	      fprintf(stderr, "%s: invalid mode: %s\n", argv[0], argv[arg]);	      exit(EX_USAGE);	    }	  }	  break;	case 'c':	  iscmd = 1;	  break;	case 'h':	default:	  usage(*optx == 'h' ? 0 : EX_USAGE);	}      }    } else {      if ( peerargc >= 3 )	usage(EX_USAGE);      peerargv[peerargc++] = argv[arg];    }  }    pargv = argv + arg;  pargc = argc - arg;    sp = getservbyname("tftp", "udp");  if (sp == 0) {    /* Use canned values */    if (verbose)      fprintf(stderr, "tftp: tftp/udp: unknown service, faking it...\n");    sp = xmalloc(sizeof(struct servent));    sp->s_name    = (char *)"tftp";    sp->s_aliases = NULL;    sp->s_port    = htons(IPPORT_TFTP);    sp->s_proto   = (char *)"udp";  }  port = sp->s_port;		/* Default port */  f = socket(AF_INET, SOCK_DGRAM, 0);  if (f < 0) {    perror("tftp: socket");    exit(EX_OSERR);  }  bzero((char *)&s_in, sizeof (s_in));  s_in.sin_family = AF_INET;  if (bind(f, (struct sockaddr *)&s_in, sizeof (s_in)) < 0) {    perror("tftp: bind");    exit(EX_OSERR);  }  bsd_signal(SIGINT, intr);  if ( peerargc ) {    /* Set peer */    if (sigsetjmp(toplevel,1) != 0)      exit(EX_NOHOST);    setpeer(peerargc, peerargv);  }  if ( iscmd && pargc ) {    /* -c specified; execute command and exit */    struct cmd *c;        if (sigsetjmp(toplevel,1) != 0)      exit(EX_UNAVAILABLE);        c = getcmd(pargv[0]);    if ( c == (struct cmd *)-1 || c == (struct cmd *)0 ) {      fprintf(stderr, "%s: invalid command: %s\n", argv[0], pargv[1]);      exit(EX_USAGE);    }	    (*c->handler)(pargc, pargv);    exit(0);  }  if (sigsetjmp(toplevel,1) != 0)    (void)putchar('\n');  #ifdef WITH_READLINE#ifdef HAVE_READLINE_HISTORY_H  using_history();#endif#endif    command();    return 0;		/* Never reached */}char    *hostname;/* Called when a command is incomplete; modifies   the global variable "line" */static voidgetmoreargs(const char *partial, const char *mprompt){#ifdef WITH_READLINE  char *eline;  int len, elen;    len = strlen(partial);  eline = readline(mprompt);  if (!eline)	  exit(0);		/* EOF */    elen = strlen(eline);  if (line)	  free(line);  line = xmalloc(len+elen+1);  strcpy(line, partial);  strcpy(line+len, eline);  free(eline);#ifdef HAVE_READLINE_HISTORY_H  add_history(line);#endif#else  int len = strlen(partial);    strcpy(line, partial);  fputs(mprompt, stdout);  if ( fgets(line+len, LBUFLEN-len, stdin) == 0 )	  if ( feof(stdin) )		  exit(0);	/* EOF */#endif}voidsetpeer(int argc, char *argv[]){	struct hostent *host;	if (argc < 2) {		getmoreargs("connect ", "(to) ");		makeargv();		argc = margc;		argv = margv;	}	if ((argc < 2) || (argc > 3)) {		printf("usage: %s host-name [port]\n", argv[0]);		return;	}	host = gethostbyname(argv[1]);	if (host == 0) {		connected = 0;		printf("%s: unknown host\n", argv[1]);		return;	}	peeraddr.sin_family = host->h_addrtype;	bcopy(host->h_addr, &peeraddr.sin_addr, host->h_length);	hostname = xstrdup(host->h_name);	port = sp->s_port;	if (argc == 3) {		struct servent *usp;		usp = getservbyname(argv[2], "udp");		if ( usp ) {			port = usp->s_port;		} else {			unsigned long myport;			char *ep;			myport = strtoul(argv[2], &ep, 10);			if (*ep || myport > 65535UL) {				printf("%s: bad port number\n", argv[2]);				connected = 0;				return;			}			port = htons((u_short)myport);		}	}	if (verbose) {		printf("Connected to %s (%s), port %u\n",		       hostname, inet_ntoa(peeraddr.sin_addr),		       (unsigned int)ntohs(port));	}	connected = 1;}voidmodecmd(int argc, char *argv[]){	const struct modes *p;	const char *sep;	if (argc < 2) {		printf("Using %s mode to transfer files.\n", mode->m_mode);		return;	}	if (argc == 2) {		for (p = modes; p->m_name; p++)			if (strcmp(argv[1], p->m_name) == 0)				break;		if (p->m_name) {			settftpmode(p);			return;		}		printf("%s: unknown mode\n", argv[1]);		/* drop through and print usage message */	}	printf("usage: %s [", argv[0]);	sep = " ";	for (p = modes; p->m_name; p++) {		printf("%s%s", sep, p->m_name);		if (*sep == ' ')			sep = " | ";	}	printf(" ]\n");

⌨️ 快捷键说明

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