Example #1
0
File: ltag.c Project: Celelibi/yafc
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);
	}
}
Example #2
0
/* 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;
}
Example #3
0
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"));
			}
		}
	}
}