/* * Get a directory listing * of remote files. */ void Connection::ls(int argc, char *argv[]) { PROC(("ls","%d [%s,%s,%s]",argc,(argc>=1)?argv[0]:"nil",(argc>=2)?argv[1]:"nil",(argc>=3)?argv[2]:"nil")); if(argc < 2) argc++, argv[1] = NULL; if(argc < 3) argc++, argv[2] = (char *)"-"; if(argc > 3) { code = -1; return; } if(argv[0][0] == 'n') recvrequest(Opt.cmdNList, argv[2], argv[1], "w"); else if(!Host.ExtList) recvrequest(Opt.cmdList, argv[2], argv[1], "w"); else { recvrequest(Host.ListCMD, argv[2], argv[1], "w"); if(code > 500 && argv[1] != NULL) recvrequest(Opt.cmdList, argv[2], argv[1], "w"); } }
/* * Receive one file. */ int Connection::getit(int argc, char *argv[], int restartit, const char *mode) { PROC(("getit"," %d %s %d [%s,%s,%s]",restartit,mode,argc,(argc>=1)?argv[0]:"nil",(argc>=2)?argv[1]:"nil",(argc>=3)?argv[2]:"nil")); if(argc == 2) { argc++; argv[2] = argv[1]; } if(argc < 3) { code = -1; return (0); } if(restartit == -1) restart_point = -1; else if(restartit) { restart_point = Fsize(argv[2]); Log(("Restart from %I64u",restart_point)); } recvrequest(Opt.cmdRetr, argv[2], argv[1], mode); restart_point = 0; return 0; }
void serve(const int sock, const char *script) { char *request; socklen_t clilen; struct sockaddr_in6 client_addr; clilen = sizeof(client_addr); while (1) { request = recvrequest(sock, (struct sockaddr*)&client_addr, &clilen); int cmp = strcmp(request, "nodeinfo"); free(request); if (cmp != 0) continue; char *msg; size_t msg_length; msg = run_script(&msg_length, script); if (sendto(sock, msg, msg_length, 0, (struct sockaddr *)&client_addr, sizeof(client_addr)) < 0) { perror("sendto failed"); exit(EXIT_FAILURE); } free(msg); } }
/* cmdlist - * Issue the LIST command and process the result. * * Returns 0 on success, -1 on error. */ int cmdlist (int argc, char *argv[]) { int bucket; /* recvrequest returns an int. I don't care * about it here. Trash it. */ char tmpname[SCPS_L_tmpnam]; if (NULL == Ltmpnam (tmpname)) { printf ("Couldn't create a temporary name\n"); return 0; } if (argc == 2) recvrequest ("LIST", tmpname, argv[1], "w", 0, &bucket); else recvrequest ("LIST", tmpname, "*", "w", 0, &bucket); interp_list (tmpname); remove (tmpname); return 0; } /* cmdlist() */
/* * Retrieve multiple files from the command line, transferring * files of the form "host:path", "ftp://host/path" using the * ftp protocol, and files of the form "http://host/path" using * the http protocol. * If path has a trailing "/", then return (-1); * the path will be cd-ed into and the connection remains open, * and the function will return -1 (to indicate the connection * is alive). * If an error occurs the return value will be the offset+1 in * argv[] of the file that caused a problem (i.e, argv[x] * returns x+1) * Otherwise, 0 is returned if all files retrieved successfully. */ int auto_fetch(int argc, char *argv[], char *outfile) { char *xargv[5]; char *cp, *url, *host, *dir, *file, *portnum; char *username, *pass, *pathstart; char *ftpproxy, *httpproxy; int rval, xargc; volatile int argpos; int dirhasglob, filehasglob, oautologin; char rempath[MAXPATHLEN]; argpos = 0; if (setjmp(toplevel)) { if (connected) disconnect(0, NULL); return (argpos + 1); } (void)signal(SIGINT, (sig_t)intr); (void)signal(SIGPIPE, (sig_t)lostpeer); if ((ftpproxy = getenv(FTP_PROXY)) != NULL && *ftpproxy == '\0') ftpproxy = NULL; if ((httpproxy = getenv(HTTP_PROXY)) != NULL && *httpproxy == '\0') httpproxy = NULL; /* * Loop through as long as there's files to fetch. */ for (rval = 0; (rval == 0) && (argpos < argc); free(url), argpos++) { if (strchr(argv[argpos], ':') == NULL) break; host = dir = file = portnum = username = pass = NULL; /* * We muck with the string, so we make a copy. */ url = strdup(argv[argpos]); if (url == NULL) errx(1, "Can't allocate memory for auto-fetch."); /* * Try HTTP URL-style arguments first. */ if (strncasecmp(url, HTTP_URL, sizeof(HTTP_URL) - 1) == 0 || #ifndef SMALL /* even if we compiled without SSL, url_get will check */ strncasecmp(url, HTTPS_URL, sizeof(HTTPS_URL) -1) == 0 || #endif /* !SMALL */ strncasecmp(url, FILE_URL, sizeof(FILE_URL) - 1) == 0) { redirect_loop = 0; if (url_get(url, httpproxy, outfile) == -1) rval = argpos + 1; continue; } /* * Try FTP URL-style arguments next. If ftpproxy is * set, use url_get() instead of standard ftp. * Finally, try host:file. */ host = url; if (strncasecmp(url, FTP_URL, sizeof(FTP_URL) - 1) == 0) { char *passend, *passagain, *userend; if (ftpproxy) { if (url_get(url, ftpproxy, outfile) == -1) rval = argpos + 1; continue; } host += sizeof(FTP_URL) - 1; dir = strchr(host, '/'); /* Look for [user:pass@]host[:port] */ /* check if we have "user:pass@" */ userend = strchr(host, ':'); passend = strchr(host, '@'); if (passend && userend && userend < passend && (!dir || passend < dir)) { username = host; pass = userend + 1; host = passend + 1; *userend = *passend = '\0'; passagain = strchr(host, '@'); if (strchr(pass, '@') != NULL || (passagain != NULL && passagain < dir)) { warnx(at_encoding_warning); goto bad_ftp_url; } if (EMPTYSTRING(username)) { bad_ftp_url: warnx("Invalid URL: %s", argv[argpos]); rval = argpos + 1; continue; } username = urldecode(username); pass = urldecode(pass); } #ifdef INET6 /* check [host]:port, or [host] */ if (host[0] == '[') { cp = strchr(host, ']'); if (cp && (!dir || cp < dir)) { if (cp + 1 == dir || cp[1] == ':') { host++; *cp++ = '\0'; } else cp = NULL; } else cp = host; } else cp = host; #else cp = host; #endif /* split off host[:port] if there is */ if (cp) { portnum = strchr(cp, ':'); pathstart = strchr(cp, '/'); /* : in path is not a port # indicator */ if (portnum && pathstart && pathstart < portnum) portnum = NULL; if (!portnum) ; else { if (!dir) ; else if (portnum + 1 < dir) { *portnum++ = '\0'; /* * XXX should check if portnum * is decimal number */ } else { /* empty portnum */ goto bad_ftp_url; } } } else portnum = NULL; } else { /* classic style `host:file' */ dir = strchr(host, ':'); } if (EMPTYSTRING(host)) { rval = argpos + 1; continue; } /* * If dir is NULL, the file wasn't specified * (URL looked something like ftp://host) */ if (dir != NULL) *dir++ = '\0'; /* * Extract the file and (if present) directory name. */ if (!EMPTYSTRING(dir)) { cp = strrchr(dir, '/'); if (cp != NULL) { *cp++ = '\0'; file = cp; } else { file = dir; dir = NULL; } } #ifndef SMALL if (debug) fprintf(ttyout, "user %s:%s host %s port %s dir %s file %s\n", username, pass ? "XXXX" : NULL, host, portnum, dir, file); #endif /* !SMALL */ /* * Set up the connection. */ if (connected) disconnect(0, NULL); xargv[0] = __progname; xargv[1] = host; xargv[2] = NULL; xargc = 2; if (!EMPTYSTRING(portnum)) { xargv[2] = portnum; xargv[3] = NULL; xargc = 3; } oautologin = autologin; if (username == NULL) anonftp = 1; else { anonftp = 0; autologin = 0; } setpeer(xargc, xargv); autologin = oautologin; if (connected == 0 || (connected == 1 && autologin && (username == NULL || !ftp_login(host, username, pass)))) { warnx("Can't connect or login to host `%s'", host); rval = argpos + 1; continue; } /* Always use binary transfers. */ setbinary(0, NULL); dirhasglob = filehasglob = 0; if (doglob) { if (!EMPTYSTRING(dir) && strpbrk(dir, "*?[]{}") != NULL) dirhasglob = 1; if (!EMPTYSTRING(file) && strpbrk(file, "*?[]{}") != NULL) filehasglob = 1; } /* Change directories, if necessary. */ if (!EMPTYSTRING(dir) && !dirhasglob) { xargv[0] = "cd"; xargv[1] = dir; xargv[2] = NULL; cd(2, xargv); if (!dirchange) { rval = argpos + 1; continue; } } if (EMPTYSTRING(file)) { #ifndef SMALL rval = -1; #else /* !SMALL */ recvrequest("NLST", "-", NULL, "w", 0, 0); rval = 0; #endif /* !SMALL */ continue; } if (verbose) fprintf(ttyout, "Retrieving %s/%s\n", dir ? dir : "", file); if (dirhasglob) { snprintf(rempath, sizeof(rempath), "%s/%s", dir, file); file = rempath; } /* Fetch the file(s). */ xargc = 2; xargv[0] = "get"; xargv[1] = file; xargv[2] = NULL; if (dirhasglob || filehasglob) { int ointeractive; ointeractive = interactive; interactive = 0; xargv[0] = "mget"; #ifndef SMALL if (resume) { xargc = 3; xargv[1] = "-c"; xargv[2] = file; xargv[3] = NULL; } #endif /* !SMALL */ mget(xargc, xargv); interactive = ointeractive; } else { if (outfile != NULL) { xargv[2] = outfile; xargv[3] = NULL; xargc++; } #ifndef SMALL if (resume) reget(xargc, xargv); else #endif /* !SMALL */ get(xargc, xargv); } if ((code / 100) != COMPLETE) rval = argpos + 1; } if (connected && rval != -1) disconnect(0, NULL); return (rval); }