void cmd_ltag(int argc, char **argv) { int i; int c; struct option longopts[] = { {"clear", no_argument, 0, 'c'}, {"info", no_argument, 0, 'i'}, {"list", no_argument, 0, 'l'}, {"load", optional_argument, 0, 'L'}, {"save", optional_argument, 0, 's'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; optind = 0; while((c = getopt_long(argc, argv, "ciL::lhs::", longopts, 0)) != EOF) { switch(c) { case 'c': list_clear(gvLocalTagList); return; case 's': save_ltaglist(optarg); return; case 'l': show_ltaglist(); return; case 'L': load_ltaglist(true, true, optarg); return; case 'i': show_ltaglist_info(); return; case 'h': print_ltag_syntax(); /* fall through */ case '?': return; } } minargs(1); for(i=1;i<argc;i++) { stripslash(argv[i]); lglob_glob(gvLocalTagList, argv[i], true, &lglob_exclude_dotdirs); } }
/* store a local file on remote server */ void cmd_put(int argc, char **argv) { int c, opt=PUT_VERBOSE; list *gl; char *put_output = 0; char *logfile = 0; pid_t pid; #ifdef HAVE_REGEX int ret; char put_rx_errbuf[129]; #endif struct option longopts[] = { {"append", no_argument, 0, 'a'}, {"delete-after", no_argument, 0, 'D'}, {"dir-mask", required_argument, 0, '3'}, #ifdef HAVE_REGEX {"dir-rx-mask", required_argument, 0, '4'}, #endif {"skip-empty", no_argument, 0, 'e'}, {"force", no_argument, 0, 'f'}, {"nohup", no_argument, 0, 'H'}, {"interactive", no_argument, 0, 'i'}, {"logfile", required_argument, 0, 'L'}, {"mask", required_argument, 0, 'm'}, #ifdef HAVE_REGEX {"rx-mask", required_argument, 0, 'M'}, #endif {"newer", no_argument, 0, 'n'}, {"output", required_argument, 0, 'o'}, {"preserve", no_argument, 0, 'p'}, {"parents", no_argument, 0, 'P'}, {"quiet", no_argument, 0, 'q'}, {"recursive", no_argument, 0, 'r'}, {"resume", no_argument, 0, 'R'}, {"skip-existing", no_argument, 0, 's'}, {"tagged", no_argument, 0, 't'}, {"type", required_argument, 0, '1'}, {"verbose", no_argument, 0, 'v'}, {"unique", no_argument, 0, 'u'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}, }; if(put_glob_mask) { free(put_glob_mask); put_glob_mask = 0; } if(put_dir_glob_mask) { free(put_dir_glob_mask); put_dir_glob_mask = 0; } #ifdef HAVE_REGEX if(put_rx_mask_set) { regfree(&put_rx_mask); put_rx_mask_set = 0; } if(put_dir_rx_mask_set) { regfree(&put_dir_rx_mask); put_dir_rx_mask_set = 0; } #endif put_skip_empty = false; optind = 0; /* force getopt() to re-initialize */ while((c = getopt_long(argc, argv, "aDefHiL:no:pPqrRstvum:M:", longopts, 0)) != EOF) { switch(c) { case 'i': opt |= PUT_INTERACTIVE; break; case 'f': opt |= PUT_FORCE; break; case 'e': opt |= PUT_SKIP_EMPTY; put_skip_empty = true; break; case '3': /* --dir-mask=GLOB */ free(put_dir_glob_mask); put_dir_glob_mask = xstrdup(optarg); unquote(put_dir_glob_mask); break; #ifdef HAVE_REGEX case '4': /* --dir-rx-mask=REGEXP */ if(put_dir_rx_mask_set) { regfree(&put_dir_rx_mask); put_dir_rx_mask_set = false; } unquote(optarg); ret = regcomp(&put_dir_rx_mask, optarg, REG_EXTENDED); if(ret != 0) { regerror(ret, &put_dir_rx_mask, put_rx_errbuf, 128); ftp_err(_("Regexp '%s' failed: %s\n"), optarg, put_rx_errbuf); return; } else put_dir_rx_mask_set = true; break; #endif case 'o': put_output = tilde_expand_home(optarg, ftp->homedir); path_collapse(put_output); stripslash(put_output); break; case 'H': opt |= PUT_NOHUP; break; case 'L': free(logfile); logfile = xstrdup(optarg); unquote(logfile); break; case 'm': /* --mask */ free(put_glob_mask); put_glob_mask = xstrdup(optarg); break; #ifdef HAVE_REGEX case 'M': /* --rx-mask */ if(put_rx_mask_set) { regfree(&put_rx_mask); put_rx_mask_set = false; } ret = regcomp(&put_rx_mask, optarg, REG_EXTENDED); if(ret != 0) { regerror(ret, &put_rx_mask, put_rx_errbuf, 128); ftp_err(_("Regexp '%s' failed: %s\n"), optind, put_rx_errbuf); return; } else put_rx_mask_set = true; break; #endif case 'n': opt |= PUT_NEWER; break; case 'v': opt |= PUT_VERBOSE; break; case 'q': opt &= ~PUT_VERBOSE; break; case 'a': opt |= PUT_APPEND; break; case 'D': opt |= PUT_DELETE_AFTER; break; case 'u': opt |= PUT_UNIQUE; if(!ftp->has_stou_command) { fprintf(stderr, _("Remote doesn't support the STOU" " (store unique) command\n")); return; } break; case 'r': opt |= PUT_RECURSIVE; break; case 's': opt |= PUT_SKIP_EXISTING; break; case 'R': opt |= PUT_RESUME; break; case 't': opt |= PUT_TAGGED; break; case '1': if(strncmp(optarg, "ascii", strlen(optarg)) == 0) opt |= PUT_ASCII; else if(strncmp(optarg, "binary", strlen(optarg)) == 0) opt |= PUT_BINARY; else { printf(_("Invalid option argument --type=%s\n"), optarg); return; } break; case 'p': opt |= PUT_PRESERVE; break; case 'P': opt |= PUT_PARENTS; break; case 'h': print_put_syntax();; return; case '?': return; } } if(optind>=argc && !test(opt, PUT_TAGGED)) { /* fprintf(stderr, _("missing argument, try 'put --help'"*/ /* " for more information\n"));*/ minargs(optind); return; } if(test(opt, PUT_APPEND) && test(opt, PUT_SKIP_EXISTING)) { printf("Can't use --append and --skip-existing simultaneously\n"); return; } need_connected(); need_loggedin(); gl = lglob_create(); while(optind < argc) { char *f; f = tilde_expand_home(argv[optind], gvLocalHomeDir); stripslash(f); lglob_glob(gl, f, true, put_exclude_func); optind++; } if(list_numitem(gl) == 0) { if(!test(opt, PUT_TAGGED)) { list_free(gl); return; } else if(list_numitem(gvLocalTagList) == 0) { printf(_("no tagged files\n")); list_free(gl); return; } } free(ftp->last_mkpath); ftp->last_mkpath = 0; put_quit = false; put_batch = put_owbatch = put_delbatch = test(opt, PUT_FORCE); if(test(opt, PUT_FORCE)) opt &= ~PUT_INTERACTIVE; if(put_output && !test(opt, PUT_RECURSIVE) && list_numitem(gl) + (test(opt, PUT_TAGGED) ? list_numitem(gvLocalTagList) : 0) == 1) { opt |= PUT_OUTPUT_FILE; } gvInTransfer = true; gvInterrupted = false; if(test(opt, PUT_NOHUP)) { int r = 0; pid = fork(); if(pid == 0) { r = transfer_init_nohup(logfile); if(r != 0) exit(0); } if(r != 0) return; if(pid == 0) { /* child process */ transfer_begin_nohup(argc, argv); if(!test(opt, PUT_FORCE) && !test(opt, PUT_RESUME)) opt |= PUT_UNIQUE; opt |= PUT_FORCE; putfiles(gl, opt, put_output); list_free(gl); if(test(opt, PUT_TAGGED)) { putfiles(gvLocalTagList, opt, put_output); list_clear(gvLocalTagList); } free(put_output); transfer_end_nohup(); } if(pid == -1) { perror("fork()"); return; } /* parent process */ sleep(1); printf("%d\n", pid); input_save_history(); gvars_destroy(); reset_xterm_title(); exit(0); } putfiles(gl, opt, put_output); list_free(gl); if(test(opt, PUT_TAGGED)) { putfiles(gvLocalTagList, opt, put_output); list_clear(gvLocalTagList); } free(put_output); gvInTransfer = false; }
static void putfiles(list *gl, unsigned opt, const char *output) { struct stat sb; char *path = 0; const char *file; listitem *li; list_sort(gl, put_sort_func, false); for(li=gl->first; li && !put_quit; li=li->next) { if(!ftp_connected()) return; if(gvSighupReceived) { if(!test(opt, PUT_RESUME)) opt |= PUT_UNIQUE; opt |= PUT_FORCE; } path = (char *)li->data; file = base_name_ptr(path); if(strcmp(file, ".") == 0 || strcmp(file, "..") == 0) continue; if(test(opt, PUT_INTERACTIVE) && !put_batch) { int a = ask(ASKYES|ASKNO|ASKCANCEL|ASKALL, ASKYES, _("Put '%s'?"), shortpath(path, 42, gvLocalHomeDir)); if(a == ASKNO) continue; if(a == ASKCANCEL) { put_quit = true; break; } if(a == ASKALL) put_batch = true; /* else a==ASKYES */ } if(stat(path, &sb) != 0) { perror(path); continue; } if(S_ISDIR(sb.st_mode)) { if(test(opt, PUT_RECURSIVE)) { char *recurs_output; char *recurs_mask; list *rgl; int r; if((put_dir_glob_mask && fnmatch(put_dir_glob_mask, base_name_ptr(path), FNM_EXTMATCH) == FNM_NOMATCH) #ifdef HAVE_REGEX || (put_dir_rx_mask_set && regexec(&put_dir_rx_mask, base_name_ptr(path), 0, 0, 0) == REG_NOMATCH) #endif ) { /*printf("skipping %s\n", path);*/ } else { if(!test(opt, PUT_PARENTS)) { asprintf(&recurs_output, "%s/%s", output ? output : ".", file); } else recurs_output = xstrdup(output ? output : "."); asprintf(&recurs_mask, "%s/*", path); rgl = lglob_create(); r = lglob_glob(rgl, recurs_mask, true, put_exclude_func); free(recurs_mask); if(list_numitem(rgl) > 0) putfiles(rgl, opt, recurs_output); free(recurs_output); } } else fprintf(stderr, _("%s: omitting directory\n"), shortpath(path, 42, gvLocalHomeDir)); continue; } if(!S_ISREG(sb.st_mode)) { fprintf(stderr, _("%s: not a regular file\n"), shortpath(path, 42, gvLocalHomeDir)); continue; } putfile(path, &sb, opt, output); if(gvInterrupted) { gvInterrupted = false; if(li->next && !put_quit && ftp_connected() && !gvSighupReceived) { int a = ask(ASKYES|ASKNO, ASKYES, _("Continue transfer?")); if(a == ASKNO) { put_quit = true; break; } /* else a == ASKYES */ fprintf(stderr, _("Excellent!!!\n")); } } } }