Beispiel #1
0
void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol)
{
	enum {
		SRC_BUF_SIZE = 45,  /* This *MUST* be a multiple of 3 */
		DST_BUF_SIZE = 4 * ((SRC_BUF_SIZE + 2) / 3),
	};
#define src_buf text
	char src[SRC_BUF_SIZE];
	FILE *fp = fp;
	ssize_t len = len;
	char dst_buf[DST_BUF_SIZE + 1];

	if (fname) {
		fp = (NOT_LONE_DASH(fname)) ? xfopen_for_read(fname) : (FILE *)text;
		src_buf = src;
	} else if (text) {
		// though we do not call uuencode(NULL, NULL) explicitly
		// still we do not want to break things suddenly
		len = strlen(text);
	} else
		return;

	while (1) {
		size_t size;
		if (fname) {
			size = fread((char *)src_buf, 1, SRC_BUF_SIZE, fp);
			if ((ssize_t)size < 0)
				bb_perror_msg_and_die(bb_msg_read_error);
		} else {
			size = len;
			if (len > SRC_BUF_SIZE)
				size = SRC_BUF_SIZE;
		}
		if (!size)
			break;
		// encode the buffer we just read in
		bb_uuencode(dst_buf, src_buf, size, bb_uuenc_tbl_base64);
		if (fname) {
			printf("%s\n", eol);
		} else {
			src_buf += size;
			len -= size;
		}
		fwrite(dst_buf, 1, 4 * ((size + 2) / 3), stdout);
	}
	if (fname && NOT_LONE_DASH(fname))
		fclose(fp);
#undef src_buf
}
Beispiel #2
0
static int ftp_send(ftp_host_info_t *server, FILE *control_stream, const char *server_path, char *local_path)
{
    struct stat sbuf;
    char buf[512];
    int fd_data;
    int fd_local;
    int response;

    /*  Connect to the data socket */
    if (ftpcmd("PASV", NULL, control_stream, buf) != 227) {
        ftp_die("PASV", buf);
    }
    fd_data = xconnect_ftpdata(server, buf);

    /* get the local file */
    fd_local = STDIN_FILENO;
    if (NOT_LONE_DASH(local_path)) {
        fd_local = xopen(local_path, O_RDONLY, 0666);
        fstat(fd_local, &sbuf);
        sprintf(buf, "ALLO %lu", (long unsigned int)sbuf.st_size);
        response = ftpcmd(buf, NULL, control_stream, buf);
        switch (response) {
        case 200:
        case 202:
            break;
        default:
            close(fd_local);
            ftp_die("ALLO", buf);
            break;
        }
    }

    response = ftpcmd("STOR", server_path, control_stream, buf);
    switch (response) {
    case 125:
    case 150:
        break;
    default:
        close(fd_local);
        ftp_die("STOR", buf);
    }

    /* transfer the file  */
    if (bb_copyfd_eof(fd_local, fd_data) == -1) {
        exit(EXIT_FAILURE);
    }

    /* close it all down */
    close(fd_data);
    if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {
        ftp_die("close", buf);
    }
    ftpcmd("QUIT", NULL, control_stream, buf);

    return EXIT_SUCCESS;
}
Beispiel #3
0
int crontab_main(int argc UNUSED_PARAM, char **argv)
{
	const struct passwd *pas;
	const char *crontab_dir = CRONTABS;
	char *tmp_fname;
	char *new_fname;
	char *user_name;  /* -u USER */
	int fd;
	int src_fd;
	int opt_ler;

	/* file [opts]     Replace crontab from file
	 * - [opts]        Replace crontab from stdin
	 * -u user         User
	 * -c dir          Crontab directory
	 * -l              List crontab for user
	 * -e              Edit crontab for user
	 * -r              Delete crontab for user
	 * bbox also supports -d == -r, but most other crontab
	 * implementations do not. Deprecated.
	 */
	enum {
		OPT_u = (1 << 0),
		OPT_c = (1 << 1),
		OPT_l = (1 << 2),
		OPT_e = (1 << 3),
		OPT_r = (1 << 4),
		OPT_ler = OPT_l + OPT_e + OPT_r,
	};

	opt_complementary = "?1:dr"; /* max one argument; -d implies -r */
	opt_ler = getopt32(argv, "u:c:lerd", &user_name, &crontab_dir);
	argv += optind;

	if (sanitize_env_if_suid()) { /* Clears dangerous stuff, sets PATH */
		/* run by non-root? */
		if (opt_ler & (OPT_u|OPT_c))
			bb_error_msg_and_die("only root can use -c or -u");
	}

	if (opt_ler & OPT_u) {
		pas = getpwnam(user_name);
		if (!pas)
			bb_error_msg_and_die("user %s is not known", user_name);
	} else {
/* XXX: xgetpwuid */
		uid_t my_uid = getuid();
		pas = getpwuid(my_uid);
		if (!pas)
			bb_perror_msg_and_die("unknown uid %d", (int)my_uid);
	}

#define user_name DONT_USE_ME_BEYOND_THIS_POINT

	/* From now on, keep only -l, -e, -r bits */
	opt_ler &= OPT_ler;
	if ((opt_ler - 1) & opt_ler) /* more than one bit set? */
		bb_show_usage();

	/* Read replacement file under user's UID/GID/group vector */
	src_fd = STDIN_FILENO;
	if (!opt_ler) { /* Replace? */
		if (!argv[0])
			bb_show_usage();
		if (NOT_LONE_DASH(argv[0])) {
			src_fd = open_as_user(pas, argv[0]);
			if (src_fd < 0)
				bb_error_msg_and_die("user %s cannot read %s",
						pas->pw_name, argv[0]);
		}
	}

	/* cd to our crontab directory */
	xchdir(crontab_dir);

	tmp_fname = NULL;

	/* Handle requested operation */
	switch (opt_ler) {

	default: /* case OPT_r: Delete */
		unlink(pas->pw_name);
		break;

	case OPT_l: /* List */
		{
			char *args[2] = { pas->pw_name, NULL };
			return bb_cat(args);
			/* list exits,
			 * the rest go play with cron update file */
		}

	case OPT_e: /* Edit */
		tmp_fname = xasprintf("%s.%u", crontab_dir, (unsigned)getpid());
		/* No O_EXCL: we don't want to be stuck if earlier crontabs
		 * were killed, leaving stale temp file behind */
		src_fd = xopen3(tmp_fname, O_RDWR|O_CREAT|O_TRUNC, 0600);
		fchown(src_fd, pas->pw_uid, pas->pw_gid);
		fd = open(pas->pw_name, O_RDONLY);
		if (fd >= 0) {
			bb_copyfd_eof(fd, src_fd);
			close(fd);
			xlseek(src_fd, 0, SEEK_SET);
		}
		close_on_exec_on(src_fd); /* don't want editor to see this fd */
		edit_file(pas, tmp_fname);
		/* fall through */

	case 0: /* Replace (no -l, -e, or -r were given) */
		new_fname = xasprintf("%s.new", pas->pw_name);
		fd = open(new_fname, O_WRONLY|O_CREAT|O_TRUNC|O_APPEND, 0600);
		if (fd >= 0) {
			bb_copyfd_eof(src_fd, fd);
			close(fd);
			xrename(new_fname, pas->pw_name);
		} else {
			bb_error_msg("cannot create %s/%s",
					crontab_dir, new_fname);
		}
		if (tmp_fname)
			unlink(tmp_fname);
		/*free(tmp_fname);*/
		/*free(new_fname);*/

	} /* switch */

	/* Bump notification file.  Handle window where crond picks file up
	 * before we can write our entry out.
	 */
	while ((fd = open(CRONUPDATE, O_WRONLY|O_CREAT|O_APPEND, 0600)) >= 0) {
		struct stat st;

		fdprintf(fd, "%s\n", pas->pw_name);
		if (fstat(fd, &st) != 0 || st.st_nlink != 0) {
			/*close(fd);*/
			break;
		}
		/* st.st_nlink == 0:
		 * file was deleted, maybe crond missed our notification */
		close(fd);
		/* loop */
	}
	if (fd < 0) {
		bb_error_msg("cannot append to %s/%s",
				crontab_dir, CRONUPDATE);
	}
	return 0;
}
Beispiel #4
0
int makedevs_main(int argc UNUSED_PARAM, char **argv)
{
	parser_t *parser;
	char *line = (char *)"-";
	int ret = EXIT_SUCCESS;

	opt_complementary = "=1"; /* exactly one param */
	getopt32(argv, "d:", &line);
	argv += optind;

	xchdir(*argv); /* ensure root dir exists */

	umask(0);

	printf("rootdir=%s\ntable=", *argv);
	if (NOT_LONE_DASH(line)) {
		printf("'%s'\n", line);
	} else {
		puts("<stdin>");
	}

	parser = config_open(line);
	while (config_read(parser, &line, 1, 1, "# \t", PARSE_NORMAL)) {
		int linenum;
		char type;
		unsigned mode = 0755;
		unsigned major = 0;
		unsigned minor = 0;
		unsigned count = 0;
		unsigned increment = 0;
		unsigned start = 0;
		char name[41];
		char user[41];
		char group[41];
		char *full_name = name;
		uid_t uid;
		gid_t gid;

		linenum = parser->lineno;

		if ((2 > sscanf(line, "%40s %c %o %40s %40s %u %u %u %u %u",
					name, &type, &mode, user, group,
					&major, &minor, &start, &increment, &count))
		 || ((unsigned)(major | minor | start | count | increment) > 255)
		) {
			bb_error_msg("invalid line %d: '%s'", linenum, line);
			ret = EXIT_FAILURE;
			continue;
		}

		gid = (*group) ? get_ug_id(group, xgroup2gid) : getgid();
		uid = (*user) ? get_ug_id(user, xuname2uid) : getuid();
		/* We are already in the right root dir,
		 * so make absolute paths relative */
		if ('/' == *full_name)
			full_name++;

		if (type == 'd') {
			bb_make_directory(full_name, mode | S_IFDIR, FILEUTILS_RECUR);
			if (chown(full_name, uid, gid) == -1) {
 chown_fail:
				bb_perror_msg("line %d: can't chown %s", linenum, full_name);
				ret = EXIT_FAILURE;
				continue;
			}
			if (chmod(full_name, mode) < 0) {
 chmod_fail:
				bb_perror_msg("line %d: can't chmod %s", linenum, full_name);
				ret = EXIT_FAILURE;
				continue;
			}
		} else if (type == 'f') {
			struct stat st;
			if ((stat(full_name, &st) < 0 || !S_ISREG(st.st_mode))) {
				bb_perror_msg("line %d: regular file '%s' does not exist", linenum, full_name);
				ret = EXIT_FAILURE;
				continue;
			}
			if (chown(full_name, uid, gid) < 0)
				goto chown_fail;
			if (chmod(full_name, mode) < 0)
				goto chmod_fail;
		} else {
			dev_t rdev;
			unsigned i;
			char *full_name_inc;

			if (type == 'p') {
				mode |= S_IFIFO;
			} else if (type == 'c') {
				mode |= S_IFCHR;
			} else if (type == 'b') {
				mode |= S_IFBLK;
			} else {
				bb_error_msg("line %d: unsupported file type %c", linenum, type);
				ret = EXIT_FAILURE;
				continue;
			}

			full_name_inc = xmalloc(strlen(full_name) + sizeof(int)*3 + 2);
			if (count)
				count--;
			for (i = start; i <= start + count; i++) {
				sprintf(full_name_inc, count ? "%s%u" : "%s", full_name, i);
				rdev = makedev(major, minor + (i - start) * increment);
				if (mknod(full_name_inc, mode, rdev) != 0
				 && errno != EEXIST
				) {
					bb_perror_msg("line %d: can't create node %s", linenum, full_name_inc);
					ret = EXIT_FAILURE;
				} else if (chown(full_name_inc, uid, gid) < 0) {
					bb_perror_msg("line %d: can't chown %s", linenum, full_name_inc);
					ret = EXIT_FAILURE;
				} else if (chmod(full_name_inc, mode) < 0) {
					bb_perror_msg("line %d: can't chmod %s", linenum, full_name_inc);
					ret = EXIT_FAILURE;
				}
			}
			free(full_name_inc);
		}
	}
	if (ENABLE_FEATURE_CLEAN_UP)
		config_close(parser);

	return ret;
}
Beispiel #5
0
int sort_main(int argc, char **argv)
{
	FILE *fp, *outfile = stdout;
	char *line, **lines = NULL;
	char *str_ignored, *str_o, *str_t;
	llist_t *lst_k = NULL;
	int i, flag;
	int linecount = 0;

	xfunc_error_retval = 2;

	/* Parse command line options */
	/* -o and -t can be given at most once */
	opt_complementary = "o--o:t--t:" /* -t, -o: maximum one of each */
			"k::"; /* -k takes list */
	getopt32(argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t);
#if ENABLE_FEATURE_SORT_BIG
	if (option_mask32 & FLAG_o) outfile = xfopen(str_o, "w");
	if (option_mask32 & FLAG_t) {
		if (!str_t[0] || str_t[1])
			bb_error_msg_and_die("bad -t parameter");
		key_separator = str_t[0];
	}
	/* parse sort key */
	while (lst_k) {
		enum {
			FLAG_allowed_for_k =
				FLAG_n | /* Numeric sort */
				FLAG_g | /* Sort using strtod() */
				FLAG_M | /* Sort date */
				FLAG_b | /* Ignore leading blanks */
				FLAG_r | /* Reverse */
				FLAG_d | /* Ignore !(isalnum()|isspace()) */
				FLAG_f | /* Force uppercase */
				FLAG_i | /* Ignore !isprint() */
			0
		};
		struct sort_key *key = add_key();
		char *str_k = lst_k->data;
		const char *temp2;

		i = 0; /* i==0 before comma, 1 after (-k3,6) */
		while (*str_k) {
			/* Start of range */
			/* Cannot use bb_strtou - suffix can be a letter */
			key->range[2*i] = str2u(&str_k);
			if (*str_k == '.') {
				str_k++;
				key->range[2*i+1] = str2u(&str_k);
			}
			while (*str_k) {
				if (*str_k == ',' && !i++) {
					str_k++;
					break;
				} /* no else needed: fall through to syntax error
					 because comma isn't in OPT_STR */
				temp2 = strchr(OPT_STR, *str_k);
				if (!temp2)
					bb_error_msg_and_die("unknown key option");
				flag = 1 << (temp2 - OPT_STR);
				if (flag & ~FLAG_allowed_for_k)
					bb_error_msg_and_die("unknown sort type");
				/* b after ',' means strip _trailing_ space */
				if (i && flag == FLAG_b) flag = FLAG_bb;
				key->flags |= flag;
				str_k++;
			}
		}
		/* leaking lst_k... */
		lst_k = lst_k->link;
	}
#endif
	/* global b strips leading and trailing spaces */
	if (option_mask32 & FLAG_b) option_mask32 |= FLAG_bb;

	/* Open input files and read data */
	for (i = argv[optind] ? optind : optind-1; argv[i]; i++) {
		fp = stdin;
		if (i >= optind && NOT_LONE_DASH(argv[i]))
			fp = xfopen(argv[i], "r");
		for (;;) {
			line = GET_LINE(fp);
			if (!line) break;
			if (!(linecount & 63))
				lines = xrealloc(lines, sizeof(char *) * (linecount + 64));
			lines[linecount++] = line;
		}
		fclose(fp);
	}
#if ENABLE_FEATURE_SORT_BIG
	/* if no key, perform alphabetic sort */
	if (!key_list)
		add_key()->range[0] = 1;
	/* handle -c */
	if (option_mask32 & FLAG_c) {
		int j = (option_mask32 & FLAG_u) ? -1 : 0;
		for (i = 1; i < linecount; i++)
			if (compare_keys(&lines[i-1], &lines[i]) > j) {
				fprintf(stderr, "Check line %d\n", i);
				return 1;
			}
		return 0;
	}
#endif
	/* Perform the actual sort */
	qsort(lines, linecount, sizeof(char *), compare_keys);
	/* handle -u */
	if (option_mask32 & FLAG_u) {
		flag = 0;
		/* coreutils 6.3 drop lines for which only key is the same */
		/* -- disabling last-resort compare... */
		option_mask32 |= FLAG_s;
		for (i = 1; i < linecount; i++) {
			if (!compare_keys(&lines[flag], &lines[i]))
				free(lines[i]);
			else
				lines[++flag] = lines[i];
		}
		if (linecount) linecount = flag+1;
	}
	/* Print it */
	for (i = 0; i < linecount; i++)
		fprintf(outfile, "%s\n", lines[i]);

	fflush_stdout_and_exit(EXIT_SUCCESS);
}
Beispiel #6
0
int md5_sha1_sum_main(int argc, char **argv)
{
	int return_value = EXIT_SUCCESS;
	uint8_t *hash_value;
	unsigned flags;
	hash_algo_t hash_algo = ENABLE_MD5SUM
		? (ENABLE_SHA1SUM ? (**argv=='m' ? HASH_MD5 : HASH_SHA1) : HASH_MD5)
		: HASH_SHA1;

	if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK)
		flags = getopt32(argc, argv, "scw");
	else optind = 1;

	if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && !(flags & FLAG_CHECK)) {
		if (flags & FLAG_SILENT) {
			bb_error_msg_and_die
				("-%c is meaningful only when verifying checksums", 's');
		} else if (flags & FLAG_WARN) {
			bb_error_msg_and_die
				("-%c is meaningful only when verifying checksums", 'w');
		}
	}

	if (argc == optind) {
		argv[argc++] = "-";
	}

	if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) {
		FILE *pre_computed_stream;
		int count_total = 0;
		int count_failed = 0;
		char *file_ptr = argv[optind];
		char *line;

		if (optind + 1 != argc) {
			bb_error_msg_and_die
				("only one argument may be specified when using -c");
		}

		pre_computed_stream = stdin;
		if (NOT_LONE_DASH(file_ptr)) {
			pre_computed_stream = xfopen(file_ptr, "r");
		}

		while ((line = xmalloc_getline(pre_computed_stream)) != NULL) {
			char *filename_ptr;

			count_total++;
			filename_ptr = strstr(line, "  ");
			/* handle format for binary checksums */
			if (filename_ptr == NULL) {
				filename_ptr = strstr(line, " *");
			}
			if (filename_ptr == NULL) {
				if (flags & FLAG_WARN) {
					bb_error_msg("invalid format");
				}
				count_failed++;
				return_value = EXIT_FAILURE;
				free(line);
				continue;
			}
			*filename_ptr = '\0';
			filename_ptr += 2;

			hash_value = hash_file(filename_ptr, hash_algo);

			if (hash_value && (strcmp((char*)hash_value, line) == 0)) {
				if (!(flags & FLAG_SILENT))
					printf("%s: OK\n", filename_ptr);
			} else {
				if (!(flags & FLAG_SILENT))
					printf("%s: FAILED\n", filename_ptr);
				count_failed++;
				return_value = EXIT_FAILURE;
			}
			/* possible free(NULL) */
			free(hash_value);
			free(line);
		}
		if (count_failed && !(flags & FLAG_SILENT)) {
			bb_error_msg("WARNING: %d of %d computed checksums did NOT match",
						 count_failed, count_total);
		}
		/*
		if (fclose_if_not_stdin(pre_computed_stream) == EOF) {
			bb_perror_msg_and_die("cannot close file %s", file_ptr);
		}
		*/
	} else {
		while (optind < argc) {
			char *file_ptr = argv[optind++];

			hash_value = hash_file(file_ptr, hash_algo);
			if (hash_value == NULL) {
				return_value = EXIT_FAILURE;
			} else {
				printf("%s  %s\n", hash_value, file_ptr);
				free(hash_value);
			}
		}
	}
	return return_value;
}
Beispiel #7
0
int tail_main(int argc, char **argv)
{
	unsigned count = 10;
	unsigned sleep_period = 1;
	bool from_top;
	int header_threshhold = 1;
	const char *str_c, *str_n, *str_s;

	char *tailbuf;
	size_t tailbufsize;
	int taillen = 0;
	int newline = 0;
	int nfiles, nread, nwrite, seen, i, opt;

	int *fds;
	char *s, *buf;
	const char *fmt;

#if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_TAIL
	/* Allow legacy syntax of an initial numeric option without -n. */
	if (argc >= 2 && (argv[1][0] == '+' || argv[1][0] == '-')
	 && isdigit(argv[1][1])
	) {
		argv[0] = (char*)"-n";
		argv--;
		argc++;
	}
#endif

	opt = getopt32(argc, argv, "fc:n:" USE_FEATURE_FANCY_TAIL("qs:v"), &str_c, &str_n, &str_s);
#define FOLLOW (opt & 0x1)
#define COUNT_BYTES (opt & 0x2)
	//if (opt & 0x1) // -f
	if (opt & 0x2) count = eat_num(str_c); // -c
	if (opt & 0x4) count = eat_num(str_n); // -n
#if ENABLE_FEATURE_FANCY_TAIL
	if (opt & 0x8) header_threshhold = INT_MAX; // -q
	if (opt & 0x10) sleep_period = xatou(str_s); // -s
	if (opt & 0x20) header_threshhold = 0; // -v
#endif
	argc -= optind;
	argv += optind;
	from_top = status;

	/* open all the files */
	fds = xmalloc(sizeof(int) * (argc + 1));
	status = nfiles = i = 0;
	if (argc == 0) {
		struct stat statbuf;

		if (!fstat(STDIN_FILENO, &statbuf) && S_ISFIFO(statbuf.st_mode)) {
			opt &= ~1; /* clear FOLLOW */
		}
		*argv = (char *) bb_msg_standard_input;
		goto DO_STDIN;
	}

	do {
		if (NOT_LONE_DASH(argv[i])) {
			fds[nfiles] = open(argv[i], O_RDONLY);
			if (fds[nfiles] < 0) {
				bb_perror_msg("%s", argv[i]);
				status = EXIT_FAILURE;
				continue;
			}
		} else {
 DO_STDIN:		/* "-" */
			fds[nfiles] = STDIN_FILENO;
		}
		argv[nfiles] = argv[i];
		++nfiles;
	} while (++i < argc);

	if (!nfiles)
		bb_error_msg_and_die("no files");

	tailbufsize = BUFSIZ;

	/* tail the files */
	if (!from_top && COUNT_BYTES) {
		if (tailbufsize < count) {
			tailbufsize = count + BUFSIZ;
		}
	}

	buf = tailbuf = xmalloc(tailbufsize);

	fmt = header_fmt + 1;	/* Skip header leading newline on first output. */
	i = 0;
	do {
		/* Be careful.  It would be possible to optimize the count-bytes
		 * case if the file is seekable.  If you do though, remember that
		 * starting file position may not be the beginning of the file.
		 * Beware of backing up too far.  See example in wc.c.
		 */
		if (!(count | from_top) && lseek(fds[i], 0, SEEK_END) >= 0) {
			continue;
		}

		if (nfiles > header_threshhold) {
			tail_xprint_header(fmt, argv[i]);
			fmt = header_fmt;
		}

		buf = tailbuf;
		taillen = 0;
		seen = 1;
		newline = 0;

		while ((nread = tail_read(fds[i], buf, tailbufsize-taillen)) > 0) {
			if (from_top) {
				nwrite = nread;
				if (seen < count) {
					if (COUNT_BYTES) {
						nwrite -= (count - seen);
						seen = count;
					} else {
						s = buf;
						do {
							--nwrite;
							if (*s++ == '\n' && ++seen == count) {
								break;
							}
						} while (nwrite);
					}
				}
				xwrite(STDOUT_FILENO, buf + nread - nwrite, nwrite);
			} else if (count) {
				if (COUNT_BYTES) {
					taillen += nread;
					if (taillen > count) {
						memmove(tailbuf, tailbuf + taillen - count, count);
						taillen = count;
					}
				} else {
					int k = nread;
					int nbuf = 0;

					while (k) {
						--k;
						if (buf[k] == '\n') {
							++nbuf;
						}
					}

					if (newline + nbuf < count) {
						newline += nbuf;
						taillen += nread;

					} else {
						int extra = 0;
						if (buf[nread-1] != '\n') {
							extra = 1;
						}

						k = newline + nbuf + extra - count;
						s = tailbuf;
						while (k) {
							if (*s == '\n') {
								--k;
							}
							++s;
						}

						taillen += nread - (s - tailbuf);
						memmove(tailbuf, s, taillen);
						newline = count - extra;
					}
					if (tailbufsize < taillen + BUFSIZ) {
						tailbufsize = taillen + BUFSIZ;
						tailbuf = xrealloc(tailbuf, tailbufsize);
					}
				}
				buf = tailbuf + taillen;
			}
		}

		if (!from_top) {
			xwrite(STDOUT_FILENO, tailbuf, taillen);
		}

		taillen = 0;
	} while (++i < nfiles);

	buf = xrealloc(tailbuf, BUFSIZ);

	fmt = NULL;

	if (FOLLOW) while (1) {
		sleep(sleep_period);
		i = 0;
		do {
			if (nfiles > header_threshhold) {
				fmt = header_fmt;
			}
			while ((nread = tail_read(fds[i], buf, sizeof(buf))) > 0) {
				if (fmt) {
					tail_xprint_header(fmt, argv[i]);
					fmt = NULL;
				}
				xwrite(STDOUT_FILENO, buf, nread);
			}
		} while (++i < nfiles);
	}

	return status;
}
Beispiel #8
0
int ftp_msend2(ftp_host_info_t *server, FILE *control_stream,
		file_path_t *file_path, int file_cnt)
{
	struct stat sbuf;
	char buf[512];
	int fd_data;
	int* fd_local = NULL;
	int response; 
	int i = 0;

	if(file_cnt == 0)
		return -1;

	fd_local = (int*)malloc(sizeof(int)*file_cnt);
	if(fd_local == NULL){
		lib_error("[%s] malloc err!!", __FUNCTION__);
		return -1;
	}

	for(i=0;i<file_cnt;i++){

		memset(buf, 0, sizeof(buf));

		/*  Connect to the data socket */
		if (ftpcmd("PASV", NULL, control_stream, buf) != 227) {
			ftp_die("PASV", buf);
		}

		fd_data = connect_ftpdata(server, buf);
		if(fd_data < 0){
			lib_error("[%s] connect_ftpdata err!!", __FUNCTION__);
			return -1;
		}

		/* get the local file */
		fd_local[i] = STDIN_FILENO;
		if (NOT_LONE_DASH(file_path[i].local_path)) {

			//printf("%d: lc_path : %s, rt_path:%s\n",i, file_path[i].local_path, file_path[i].server_path);
			fd_local[i] = open(file_path[i].local_path, O_RDONLY, 0666);
			if(fd_local[i] < 0){
				lib_error("[%s] open err!!", __FUNCTION__);
				close(fd_data);
				return -1;
			}
			fstat(fd_local[i], &sbuf);

			sprintf(buf, "ALLO %"OFF_FMT"u", sbuf.st_size);
			response = ftpcmd(buf, NULL, control_stream, buf);
			switch (response) {
			case 200:
			case 202:
				break;
			default:
				ftp_die("ALLO", buf);
				break;
			}
		}

		response = ftpcmd("STOR", file_path[i].server_path, control_stream, buf);
		switch (response) {
		case 125:
		case 150:
			break;
		default:
			ftp_die("STOR", buf);
			close(fd_local[i]);
			close(fd_data);
			goto ftp_msend_quit_error;
		}

		/* transfer the file  */
		if (copyfd_eof(fd_local[i], fd_data, 0) == -1) {
			close(fd_data);
			close(fd_local[i]);
			goto ftp_msend_quit_error;
		}

		/* close it all down */
		close(fd_local[i]);

		close(fd_data);
		if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {
			ftp_die("close", buf);
		}

	}

	ftpcmd("QUIT", NULL, control_stream, buf);
	return 0;

ftp_msend_quit_error:
	ftpcmd("QUIT", NULL, control_stream, buf);
	return -1;
}
Beispiel #9
0
int ftp_send(ftp_host_info_t *server, FILE *control_stream,
		const char *server_path, char *local_path)
{
	struct stat sbuf;
	char buf[512];
	int fd_data;
	int fd_local;
	int response; 
	
	/*  Connect to the data socket */
	if (ftpcmd("PASV", NULL, control_stream, buf) != 227) {
		ftp_die("PASV", buf);
	}

	fd_data = connect_ftpdata(server, buf);
	if(fd_data < 0){
		lib_error("[%s] connect_ftpdata err!!", __FUNCTION__);
		return -1;
	}

	/* get the local file */
	fd_local = STDIN_FILENO;
	if (NOT_LONE_DASH(local_path)) {
		fd_local = open(local_path, O_RDONLY, 0666);
		if(fd_local < 0){
			lib_error("[%s] open err!!", __FUNCTION__);
			close(fd_data);
			return -1;
		}
		fstat(fd_local, &sbuf);

		sprintf(buf, "ALLO %"OFF_FMT"u", sbuf.st_size);
		response = ftpcmd(buf, NULL, control_stream, buf);
		switch (response) {
		case 200:
		case 202:
			break;
		default:
			ftp_die("ALLO", buf);
			break;
		}
	}
	response = ftpcmd("STOR", server_path, control_stream, buf);
	switch (response) {
	case 125:
	case 150:
		break;
	default:
		ftp_die("STOR", buf);
		close(fd_local);
		close(fd_data);
		return -1;

	}

	/* transfer the file  */
	if (copyfd_eof(fd_local, fd_data, 0) == -1) {
		close(fd_data);
		close(fd_local);
		return -1;
	}

	/* close it all down */
	close(fd_local);
	close(fd_data);
	if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {
		ftp_die("close", buf);
	}
	//ftpcmd("NOOP", NULL, control_stream, buf);
	ftpcmd("QUIT", NULL, control_stream, buf);

	return 0;
}