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

📄 rcp.c

📁 压缩包中包含LINUX下多个命令的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1983, 1990, 1992, 1993, 2002 *	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. * 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. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1983, 1990, 1992, 1993\n\	The Regents of the University of California.  All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)rcp.c	8.2 (Berkeley) 4/2/94";#endif /* not lint */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <sys/param.h>#include <sys/stat.h>#ifdef TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# ifdef HAVE_SYS_TIME_H#  include <sys/time.h># else#  include <time.h># endif#endif#include <sys/socket.h>#include <netinet/in.h>#ifdef HAVE_NETINET_IN_SYSTM_H#include <netinet/in_systm.h>#endif#ifdef HAVE_NETINET_IP_H#include <netinet/ip.h>#endif#include <ctype.h>#include <dirent.h>#include <err.h>#include <errno.h>#include <fcntl.h>#include <netdb.h>#include <pwd.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <string.h>#include <unistd.h>#include <getopt.h>#ifndef HAVE_UTIMES#include <utime.h> /* If we don't have utimes(), use utime(). */#endif#include "extern.h"#if !HAVE_DECL_STRERRORextern const char *strerror __P ((int));#endif#ifdef KERBEROS# include <kerberosIV/des.h># include <kerberosIV/krb.h>char	dst_realm_buf[REALM_SZ];char	*dest_realm = NULL;int	use_kerberos = 1;CREDENTIALS 	cred;Key_schedule	schedule;extern	char	*krb_realmofhost ();# ifdef CRYPTint	doencrypt = 0;# define	OPTIONS	"dfKk:prtx"# else#  define	OPTIONS	"dfKk:prt"# endif#else# define	OPTIONS "dfprt"#endif /* KERBEROS  */#if !defined (S_ISTXT) && defined (S_ISVTX)#define S_ISTXT S_ISVTX#endifstatic const char *short_options = OPTIONS;static struct option long_options[] ={  { "recursive", required_argument, 0, 'r' },  { "preserve", no_argument, 0, 'p' },#ifdef KERBEROS  { "kerberos", no_argument, 0, 'K' },  { "realm", required_argument, 0, 'k' },# ifdef CRYPT  { "encrypt", no_argument, 0, 'x' },# endif#endif  { "help", no_argument, 0, 'h' },  { "version", no_argument, 0, 'V' },  /* Server option.  */  { "directory", required_argument, 0, 'd' },  { "from", required_argument, 0, 'f' },  { "to", required_argument, 0, 't' },  { 0, 0, 0, 0 }};struct passwd *pwd;u_short	port;uid_t	userid;int errs, rem;int pflag, iamremote, iamrecursive, targetshouldbedirectory;#define	CMDNEEDS	64char cmd[CMDNEEDS];		/* must hold "rcp -r -p -d\0" */#ifdef KERBEROSint	 kerberos __P ((char **, char *, char *, char *));void	 oldw __P ((const char *, ...));#endifint	 response __P ((void));void	 rsource __P ((char *, struct stat *));void	 sink __P ((int, char *[]));void	 source __P ((int, char *[]));void	 tolocal __P ((int, char *[]));void	 toremote __P ((char *, int, char *[]));void	 usage __P ((void));void	 help __P ((void));intmain (int argc, char *argv[]){  struct servent *sp;  int ch, fflag, tflag;  char *targ;  const char *shell;#ifndef HAVE___PROGNAME  extern char *__progname;  __progname = argv[0];#endif  fflag = tflag = 0;  while ((ch = getopt_long (argc, argv, short_options, long_options, 0))	 != EOF)    switch(ch)      {			/* User-visible flags. */      case 'K':#ifdef KERBEROS	use_kerberos = 0;#endif	break;#ifdef	KERBEROS      case 'k':	dest_realm = dst_realm_buf;	strncpy(dst_realm_buf, optarg, REALM_SZ);	break;#ifdef CRYPT      case 'x':	doencrypt = 1;	/* des_set_key(cred.session, schedule); */	break;#endif#endif      case 'p':	pflag = 1;	break;      case 'r':	iamrecursive = 1;	break;	/* Server options. */      case 'd':	targetshouldbedirectory = 1;	break;      case 'f':			/* "from" */	iamremote = 1;	fflag = 1;	break;      case 't':			/* "to" */	iamremote = 1;	tflag = 1;	break;      case 'V':	printf ("rcp (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);	exit (0);	break;      case 'h':	help ();	break;      case '?':      default:	usage ();      }  argc -= optind;  argv += optind;#ifdef KERBEROS  if (use_kerberos)    {#ifdef CRYPT      shell = doencrypt ? "ekshell" : "kshell";#else      shell = "kshell";#endif      if ((sp = getservbyname (shell, "tcp")) == NULL)	{	  use_kerberos = 0;	  oldw ("can't get entry for %s/tcp service", shell);	  sp = getservbyname (shell = "shell", "tcp");	}    } else      sp = getservbyname (shell = "shell", "tcp");#else  sp = getservbyname (shell = "shell", "tcp");#endif  if (sp == NULL)    errx (1, "%s/tcp: unknown service", shell);  port = sp->s_port;  if ((pwd = getpwuid (userid = getuid ())) == NULL)    errx(1, "unknown user %d", (int)userid);  rem = STDIN_FILENO;		/* XXX */  if (fflag)    {			/* Follow "protocol", send data. */      response ();      setuid (userid);      source (argc, argv);      exit (errs);    }  if (tflag)    {			/* Receive data. */      setuid (userid);      sink (argc, argv);      exit (errs);    }  if (argc < 2)    usage ();  if (argc > 2)    targetshouldbedirectory = 1;  rem = -1;  /* Command to be executed on remote system using "rsh". */#ifdef	KERBEROS  snprintf (cmd, sizeof cmd, "rcp%s%s%s%s", iamrecursive ? " -r" : "",#ifdef CRYPT		  (doencrypt && use_kerberos ? " -x" : ""),#else		  "",#endif		  pflag ? " -p" : "", targetshouldbedirectory ? " -d" : "");#else  snprintf (cmd, sizeof cmd, "rcp%s%s%s",	    iamrecursive ? " -r" : "", pflag ? " -p" : "",	    targetshouldbedirectory ? " -d" : "");#endif  signal (SIGPIPE, lostconn);  targ = colon (argv[argc - 1]);	/* Dest is remote host. */  if (targ)	/* Dest is remote host. */    toremote (targ, argc, argv);  else    {      tolocal (argc, argv);		/* Dest is local host. */      if (targetshouldbedirectory)	verifydir(argv[argc - 1]);    }  exit (errs);}voidtoremote (char *targ, int argc, char *argv[]){  int i, len, tos;  char *bp, *host, *src, *suser, *thost, *tuser;  *targ++ = 0;  if (*targ == 0)    targ = ".";  thost = strchr (argv[argc - 1], '@');  if (thost)    {      /* user@host */      *thost++ = 0;      tuser = argv[argc - 1];      if (*tuser == '\0')	tuser = NULL;      else if (!okname(tuser))	exit (1);    }  else    {      thost = argv[argc - 1];      tuser = NULL;    }  for (i = 0; i < argc - 1; i++)    {      src = colon (argv[i]);      if (src)	{			/* remote to remote */	  *src++ = 0;	  if (*src == 0)	    src = ".";	  host = strchr (argv[i], '@');	  len = strlen (PATH_RSH) + strlen (argv[i]) +	    strlen (src) + (tuser ? strlen (tuser) : 0) +	    strlen (thost) + strlen (targ) + CMDNEEDS + 20;	  if (!(bp = malloc (len)))	    err (1, NULL);	  if (host)	    {	      *host++ = 0;	      suser = argv[i];	      if (*suser == '\0')		suser = pwd->pw_name;	      else if (!okname (suser))		continue;	      snprintf (bp, len,			"%s %s -l %s -n %s %s '%s%s%s:%s'",			PATH_RSH, host, suser, cmd, src,			tuser ? tuser : "", tuser ? "@" : "",			thost, targ);	    }	  else	    snprintf (bp, len,		      "exec %s %s -n %s %s '%s%s%s:%s'",		      PATH_RSH, argv[i], cmd, src,		      tuser ? tuser : "", tuser ? "@" : "",		      thost, targ);	  susystem (bp, userid);	  free (bp);	}      else	{			/* local to remote */	  if (rem == -1)	    {	      len = strlen (targ) + CMDNEEDS + 20;	      if (!(bp = malloc (len)))		err (1, NULL);	      snprintf (bp, len, "%s -t %s", cmd, targ);	      host = thost;#ifdef KERBEROS	      if (use_kerberos)		rem = kerberos (&host, bp, pwd->pw_name,				tuser ? tuser : pwd->pw_name);	      else#endif		rem = rcmd (&host, port, pwd->pw_name,			    tuser ? tuser : pwd->pw_name, bp, 0);	      if (rem < 0)		exit (1);#if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_THROUGHPUT)	      tos = IPTOS_THROUGHPUT;	      if (setsockopt (rem, IPPROTO_IP, IP_TOS,			      (char *) &tos, sizeof(int)) < 0)		warn("TOS (ignored)");#endif	      if (response () < 0)		exit(1);	      free(bp);	      setuid(userid);	    }	  source(1, argv+i);	}    }}voidtolocal (int argc, char *argv[]){  int i, len, tos;  char *bp, *host, *src, *suser;  for (i = 0; i < argc - 1; i++)    {      if (!(src = colon (argv[i])))	{		/* Local to local. */	  len = strlen (PATH_CP) + strlen (argv[i]) +	    strlen (argv[argc - 1]) + 20;	  if (!(bp = malloc (len)))	    err (1, NULL);	  snprintf (bp, len, "exec %s%s%s %s %s", PATH_CP,		    iamrecursive ? " -r" : "", pflag ? " -p" : "",		    argv[i], argv[argc - 1]);	  if (susystem (bp, userid))	    ++errs;	  free (bp);	  continue;	}      *src++ = 0;      if (*src == 0)	src = ".";      if ((host = strchr(argv[i], '@')) == NULL)	{	  host = argv[i];	  suser = pwd->pw_name;	}      else	{	  *host++ = 0;	  suser = argv[i];	  if (*suser == '\0')	    suser = pwd->pw_name;	  else if (!okname (suser))	    continue;	}      len = strlen (src) + CMDNEEDS + 20;      if ((bp = malloc (len)) == NULL)	err (1, NULL);      snprintf (bp, len, "%s -f %s", cmd, src);      rem =#ifdef KERBEROS	use_kerberos ? kerberos(&host, bp, pwd->pw_name, suser) :#endif	rcmd (&host, port, pwd->pw_name, suser, bp, 0);      free (bp);      if (rem < 0)	{	  ++errs;	  continue;	}      seteuid (userid);#if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_THROUGHPUT)      tos = IPTOS_THROUGHPUT;      if (setsockopt (rem, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof (int)) < 0)	warn ("TOS (ignored)");#endif      sink (1, argv + argc - 1);      seteuid (0);      close (rem);      rem = -1;    }}static intwrite_stat_time (int fd, struct stat *stat){  char buf[4 * sizeof (long) * 3 + 2];  time_t a_sec, m_sec;  long a_usec = 0, m_usec = 0;#ifdef HAVE_STAT_ST_MTIMESPEC  a_sec = stat->st_atimespec.ts_sec;  a_usec = stat->st_atimespec.ts_nsec / 1000;  m_sec = stat->st_mtimespec.ts_sec;  m_usec = stat->st_mtimespec.ts_nsec / 1000;#else  a_sec = stat->st_atime;  m_sec = stat->st_mtime;#ifdef HAVE_STAT_ST_MTIME_USEC  a_usec = stat->st_atime_usec;  m_usec = stat->st_mtime_usec;#endif#endif  snprintf (buf, sizeof(buf), "T%ld %ld %ld %ld\n",	    a_sec, a_usec, m_sec, m_usec);  return write (fd, buf, strlen (buf));}voidsource (int argc, char *argv[]){  struct stat stb;  static BUF buffer;  BUF *bp;  off_t i;  int amt, fd, haderr, indx, result;  char *last, *name, buf[BUFSIZ];  for (indx = 0; indx < argc; ++indx)    {      name = argv[indx];      if ((fd = open (name, O_RDONLY, 0)) < 0)	goto syserr;      if (fstat (fd, &stb))	{	syserr:	  run_err ("%s: %s", name, strerror (errno));	  goto next;	}      switch (stb.st_mode & S_IFMT)	{	case S_IFREG:	  break;	case S_IFDIR:	  if (iamrecursive)	    {	      rsource (name, &stb);	      goto next;	    }	  /* FALLTHROUGH */	default:	  run_err ("%s: not a regular file", name);	  goto next;	}      if ((last = strrchr (name, '/')) == NULL)	last = name;      else	++last;      if (pflag)	{	  write_stat_time (rem, &stb);	  if (response() < 0)	    goto next;	}#define	RCP_MODEMASK	(S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO)      snprintf(buf, sizeof buf,	       (sizeof(stb.st_size) > sizeof(long)		? "C%04o %qd %s\n"		: "C%04o %ld %s\n"),	       stb.st_mode & RCP_MODEMASK, stb.st_size, last);      write (rem, buf, strlen (buf));      if (response () < 0)	goto next;      if ((bp = allocbuf (&buffer, fd, BUFSIZ)) == NULL)	{	next:	  close (fd);	  continue;	}      /* Keep writing after an error so that we stay sync'd up. */      for (haderr = i = 0; i < stb.st_size; i += bp->cnt)	{	  amt = bp->cnt;	  if (i + amt > stb.st_size)	    amt = stb.st_size - i;	  if (!haderr)	    {	      result = read (fd, bp->buf, amt);

⌨️ 快捷键说明

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