home *** CD-ROM | disk | FTP | other *** search
- /*
- * rcp.c: NOT the Berkeley version.
- *
- * rcp [system!]source ... [system!]dest
- * e.g. rcp a!file1 b!file2 c!/usr/tmp
- *
- * AUTHOR: Dave Settle, THORN EMI SMB Business Software, June 86
- *
- * Electronic address:
- * dave%smb@ukc
- * dave@smb.co.uk
- *
- */
- #include <stdio.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/utsname.h>
- #include <pwd.h>
-
- #define MAIN
- #include "ni.h"
- #include "ftp.h"
-
- extern int debug;
-
- char *getenv(), *getlogin();
- char *sysname(), *filename(), *lastpart();
- struct passwd *getpwuid(), *getpwnam();
- struct request request;
- time_t time(), interval();
- long kbytes();
-
- die(sig){
- struct request req;
- if(sig) printf("\r\n%s: server terminated\n",
- (sig == SIGINT) ? "Interrupt" : "Quit");
- send(&req, 0, TERMINATE, server);
- exit(1);
- }
-
- extern char *panicstr;
- panic(sig){
- printf("server has terminated me: %s\n",
- panicstr ? panicstr : "no reason");
- exit(0);
- }
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- /*
- * check if the destination is local or remote.
- */
- int i, n, start = 1;
- struct utsname uts;
- char *user;
- struct passwd *pw;
- register struct request *r = &request;
- user = getenv("LOGNAME");
- if(user == NULL) printf("who are you?\n");
- /*
- * find out node name
- */
- uname(&uts);
- strncpy(localnode, uts.nodename, sizeof uts.nodename);
- #ifdef DEBUG
- printf("localnode: %s\n", localnode);
- #endif
- hostname = NULL;
- for(i=1;i<argc;i++) {
- if(*argv[i] == '-') {
- switch(argv[i][1]) {
- case 'd':
- debug = 1;
- start = i + 1;
- break;
- }
- continue;
- }
- if(remote(argv[i])) {
- if(hostname && strcmp(hostname, sysname(argv[i]))) {
- printf("Cannot talk to %s AND %s!\n",
- hostname, sysname(argv[i]));
- exit(1);
- }
- else hostname = sysname(argv[i]);
- }
- }
- /*
- * If this isn't really a remote copy, subsitute 'cp'
- */
- if(hostname == 0) {
- argv[0] = "cp";
- argv[argc] = 0;
- execv("/bin/cp", argv);
- exit(1);
- }
- if((i = hostaddr(hostname)) == -1) {
- printf("Host '%s' not known\n", hostname);
- exit(1);
- }
- else server[NODE] = i;
- if(configure(client, WINDOW, getpid()) == -1) {
- perror("/dev/ni");
- exit(1);
- }
- /*
- * send off our login name and uid to remote host.
- * also send term type.
- */
- if((user = getlogin()) == NULL)
- pw = getpwuid(getuid());
- else
- pw = getpwnam(user);
- if(pw == NULL) {
- printf("Can't determine your user name!\n");
- exit(1);
- }
- if(*pw->pw_name == 0) {
- printf("Your user name is NULL! You seem to be %s\n",
- user ? user : "unknown");
- exit(1);
- }
- printf("Trying to connect to %s ... ", ipaddr(server));
- fflush(stdout);
- sprintf(r->r_data, "%d %s TERM=%s",
- pw->pw_uid, pw->pw_name, getenv("TERM"));
- n = strlen(r->r_data);
- send(r, n, REQUEST, server);
- recv(r);
- if(r->r_type != ACCEPT) {
- printf("rejected!\n%s: %s\n", hostname, r->r_data);
- exit(0);
- }
- memcpy(server, r->r_port.srcaddr, ETHERSIZE);
- printf("OK\nStarting remote file server ... "); fflush(stdout);
- /*
- * trap signals from here on, so that we can terminate the remote side.
- */
- signal(SIGQUIT, die);
- signal(SIGINT, die);
- signal(SIGHUP, die);
- signal(SIGTERM, panic);
- n = sprintf(r->r_data, "fileserver");
- send(r, n, REQUEST, server);
- recv(r);
- if(r->r_type != ACCEPT) {
- printf("rejected!\n%s: %s\n", hostname, r->r_data);
- exit(1);
- }
- printf("OK\n");
- /*
- * Now send (or receive) the files.
- */
- if(remote(argv[argc - 1]))
- for(i=start;i<(argc - 1);i++)
- sendit(filename(argv[i]), filename(argv[argc - 1]));
- else
- for(i=start;i<(argc - 1);i++)
- getit(filename(argv[i]), filename(argv[argc - 1]));
- die(0);
- /*NOTREACHED*/
- }
- /*
- * sendit: send local filename to remote server.
- */
- sendit(local, remote)
- char *local, *remote;
- {
- register int n, f;
- register struct request *r = &request;
- time_t start;
- struct stat statb;
- long kb;
- if((f = open(local, 0)) == -1) {
- perror(local);
- return(-1);
- }
- n = sprintf(r->r_data, "%d %s %s", fmode(local), local, remote);
- printf("%s: ", local); fflush(stdout);
- send(r, n, PUTFILE, server);
- recv(r);
- stat(local, &statb);
- start = time((long *) 0);
- kb = kbytes(statb.st_size);
- if(r->r_type == ACCEPT) {
- printf("[sending] "); fflush(stdout);
- if(ftpout(f, server))
- printf("OK (%d kb/sec)\n", kb / interval(start));
- }
- else printf("[%s] %s\n", hostname, r->r_data);
- close(f);
- return(0);
- }
- /*
- * getit: persuade remote host to send a file.
- */
- getit(remote, local)
- char *local, *remote;
- {
- register struct request *r = &request;
- register int n, f;
- int mode;
- char fname[128];
- time_t start;
- struct stat statb;
- long kb;
- int newfile;
- strcpy(fname, local);
- if(stat(local, &statb) != -1) {
- if((statb.st_mode & S_IFMT) == S_IFDIR)
- sprintf(fname, "%s/%s", local, lastpart(remote));
- newfile = 0;
- }
- else newfile = 1;
- if((f = creat(fname, 0666)) == -1) {
- perror(fname);
- return(-1);
- }
- n = sprintf(r->r_data, "%s", remote);
- printf("%s: ", fname); fflush(stdout);
- send(r, n, SENDFILE, server);
- recv(r);
- if(r->r_type == ACCEPT) {
- sscanf(r->r_data, "%d", &mode);
- if(newfile) chmod(fname, mode);
- start = time((long *) 0);
- printf("[receiving] "); fflush(stdout);
- if(ftpin(f, server, &kb))
- printf("OK (%d kb/sec)\n", kbytes(kb) / interval(start));
- else unlink(fname);
- close(f);
- return(0);
- }
- else {
- printf("rejected [%s: %s]\n", hostname, r->r_data);
- close(f);
- return(-1);
- }
- }
- long kbytes(size)
- long size;
- {
- size >>= 10;
- return(size ? size : 1);
- }
- long interval(start)
- {
- long i = time((long *) 0) - start;
- return(i ? i : 1);
- }
-