home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / 3bconnect / rcp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-05-08  |  5.4 KB  |  254 lines

  1. /*
  2.  * rcp.c: NOT the Berkeley version.
  3.  *
  4.  * rcp [system!]source ... [system!]dest
  5.  * e.g. rcp a!file1 b!file2 c!/usr/tmp
  6.  *
  7.  * AUTHOR: Dave Settle, THORN EMI SMB Business Software, June 86
  8.  *
  9.  * Electronic address:
  10.  *        dave%smb@ukc
  11.  *        dave@smb.co.uk
  12.  *
  13.  */
  14. #include <stdio.h>
  15. #include <errno.h>
  16. #include <sys/types.h>
  17. #include <sys/stat.h>
  18. #include <sys/utsname.h>
  19. #include <pwd.h>
  20.  
  21. #define MAIN
  22. #include "ni.h"
  23. #include "ftp.h"
  24.  
  25. extern int debug;
  26.  
  27. char *getenv(), *getlogin();
  28. char *sysname(), *filename(), *lastpart();
  29. struct passwd *getpwuid(), *getpwnam();
  30. struct request request;
  31. time_t time(), interval();
  32. long kbytes();
  33.  
  34. die(sig){
  35.     struct request req;
  36.     if(sig) printf("\r\n%s: server terminated\n", 
  37.         (sig == SIGINT) ? "Interrupt" : "Quit");
  38.     send(&req, 0, TERMINATE, server);
  39.     exit(1);
  40. }
  41.  
  42. extern char *panicstr;
  43. panic(sig){
  44.     printf("server has terminated me: %s\n", 
  45.         panicstr ? panicstr : "no reason");
  46.     exit(0);
  47. }
  48.  
  49. main(argc, argv)
  50. int argc;
  51. char **argv;
  52. {
  53. /*
  54.  * check if the destination is local or remote.
  55.  */
  56.     int i, n, start = 1;
  57.     struct utsname uts;
  58.     char *user;
  59.     struct passwd *pw;
  60.     register struct request *r = &request;
  61.     user = getenv("LOGNAME");
  62.     if(user == NULL) printf("who are you?\n");
  63. /*
  64.  * find out node name
  65.  */
  66.      uname(&uts);
  67.      strncpy(localnode, uts.nodename, sizeof uts.nodename);
  68. #ifdef DEBUG
  69.     printf("localnode: %s\n", localnode);
  70. #endif
  71.     hostname = NULL;
  72.     for(i=1;i<argc;i++) {
  73.         if(*argv[i] == '-') {
  74.             switch(argv[i][1]) {
  75.             case 'd':
  76.                 debug = 1;
  77.                 start = i + 1;
  78.                 break;
  79.             }
  80.             continue;
  81.         }
  82.         if(remote(argv[i])) {
  83.             if(hostname && strcmp(hostname, sysname(argv[i]))) {
  84.                 printf("Cannot talk to %s AND %s!\n",
  85.                     hostname, sysname(argv[i]));
  86.                 exit(1);
  87.             }
  88.             else hostname = sysname(argv[i]);
  89.         }
  90.     }
  91. /*
  92.  * If this isn't really a remote copy, subsitute 'cp'
  93.  */
  94.     if(hostname == 0) {
  95.         argv[0] = "cp";
  96.         argv[argc] = 0;
  97.         execv("/bin/cp", argv);
  98.         exit(1);
  99.     }
  100.     if((i = hostaddr(hostname)) == -1) {
  101.         printf("Host '%s' not known\n", hostname);
  102.         exit(1);
  103.     }
  104.     else server[NODE] = i;
  105.     if(configure(client, WINDOW, getpid()) == -1) {
  106.         perror("/dev/ni");
  107.         exit(1);
  108.     }
  109. /*
  110.  * send off our login name and uid to remote host.
  111.  * also send term type.
  112.  */
  113.      if((user = getlogin()) == NULL) 
  114.          pw = getpwuid(getuid());
  115.      else
  116.          pw = getpwnam(user);
  117.      if(pw == NULL) {
  118.          printf("Can't determine your user name!\n");
  119.          exit(1);
  120.      }
  121.      if(*pw->pw_name == 0) {
  122.          printf("Your user name is NULL! You seem to be %s\n",
  123.              user ? user : "unknown");
  124.          exit(1);
  125.      }
  126.     printf("Trying to connect to %s ... ", ipaddr(server));
  127.      fflush(stdout);
  128.     sprintf(r->r_data, "%d %s TERM=%s", 
  129.         pw->pw_uid, pw->pw_name, getenv("TERM"));
  130.     n = strlen(r->r_data);
  131.     send(r, n, REQUEST, server);
  132.     recv(r);
  133.      if(r->r_type != ACCEPT) {
  134.          printf("rejected!\n%s: %s\n", hostname, r->r_data);
  135.          exit(0);
  136.      }
  137.     memcpy(server, r->r_port.srcaddr, ETHERSIZE);
  138.     printf("OK\nStarting remote file server ... "); fflush(stdout);
  139. /*
  140.  * trap signals from here on, so that we can terminate the remote side.
  141.  */
  142.     signal(SIGQUIT, die);
  143.     signal(SIGINT, die);
  144.     signal(SIGHUP, die);
  145.     signal(SIGTERM, panic);
  146.     n = sprintf(r->r_data, "fileserver");
  147.     send(r, n, REQUEST, server);
  148.     recv(r);
  149.     if(r->r_type != ACCEPT) {
  150.         printf("rejected!\n%s: %s\n", hostname, r->r_data);
  151.         exit(1);
  152.     }
  153.     printf("OK\n");
  154. /*
  155.  * Now send (or receive) the files.
  156.  */
  157.     if(remote(argv[argc - 1])) 
  158.         for(i=start;i<(argc - 1);i++) 
  159.             sendit(filename(argv[i]), filename(argv[argc - 1]));
  160.     else
  161.         for(i=start;i<(argc - 1);i++) 
  162.             getit(filename(argv[i]), filename(argv[argc - 1]));
  163.     die(0);    
  164.     /*NOTREACHED*/
  165. }
  166. /*
  167.  * sendit: send local filename to remote server.
  168.  */
  169. sendit(local, remote)
  170. char *local, *remote;
  171. {
  172.     register int n, f;
  173.     register struct request *r = &request;
  174.     time_t start;
  175.     struct stat statb;
  176.     long kb;
  177.     if((f = open(local, 0)) == -1) {
  178.         perror(local);
  179.         return(-1);
  180.     }
  181.     n = sprintf(r->r_data, "%d %s %s", fmode(local), local, remote);
  182.     printf("%s: ", local); fflush(stdout);
  183.     send(r, n, PUTFILE, server);
  184.     recv(r);
  185.     stat(local, &statb);
  186.     start = time((long *) 0);
  187.     kb = kbytes(statb.st_size);
  188.     if(r->r_type == ACCEPT) {
  189.         printf("[sending] "); fflush(stdout);
  190.         if(ftpout(f, server)) 
  191.             printf("OK (%d kb/sec)\n", kb / interval(start));
  192.     }
  193.     else printf("[%s] %s\n", hostname, r->r_data);
  194.     close(f);
  195.     return(0);
  196. }
  197. /*
  198.  * getit: persuade remote host to send a file.
  199.  */
  200. getit(remote, local)
  201. char *local, *remote;
  202. {
  203.     register struct request *r = &request;
  204.     register int n, f;
  205.     int mode;
  206.     char fname[128];
  207.     time_t start;
  208.     struct stat statb;
  209.     long kb;
  210.     int newfile;
  211.     strcpy(fname, local);
  212.     if(stat(local, &statb) != -1) {
  213.         if((statb.st_mode & S_IFMT) == S_IFDIR)
  214.             sprintf(fname, "%s/%s", local, lastpart(remote));
  215.         newfile = 0;
  216.     }
  217.     else newfile = 1;
  218.     if((f = creat(fname, 0666)) == -1) {
  219.         perror(fname);
  220.         return(-1);
  221.     }
  222.     n = sprintf(r->r_data, "%s", remote);
  223.     printf("%s: ", fname); fflush(stdout);
  224.     send(r, n, SENDFILE, server);
  225.     recv(r);
  226.     if(r->r_type == ACCEPT) {
  227.         sscanf(r->r_data, "%d", &mode);
  228.         if(newfile) chmod(fname, mode);
  229.         start = time((long *) 0);
  230.         printf("[receiving] "); fflush(stdout);
  231.         if(ftpin(f, server, &kb))
  232.             printf("OK (%d kb/sec)\n", kbytes(kb) / interval(start));
  233.         else unlink(fname);
  234.         close(f);
  235.         return(0);
  236.     }
  237.     else {
  238.         printf("rejected [%s: %s]\n", hostname, r->r_data);
  239.         close(f);
  240.         return(-1);
  241.     }
  242. }
  243. long kbytes(size)
  244. long size;
  245. {
  246.     size >>= 10;
  247.     return(size ? size : 1);
  248. }
  249. long interval(start)
  250. {
  251.     long i = time((long *) 0) - start;
  252.     return(i ? i : 1);
  253. }
  254.