int tar_main(int argc, char **argv)
{
	char (*get_header_ptr)(archive_handle_t *) = get_header_tar;
	archive_handle_t *tar_handle;
	char *base_dir = NULL;
	const char *tar_filename = "-";
	unsigned long opt;
	unsigned long ctx_flag = 0;

	if (argc < 2) {
		bb_show_usage();
	}

	/* Prepend '-' to the first argument if required */
	if (argv[1][0] != '-') {
		char *tmp;

		bb_xasprintf(&tmp, "-%s", argv[1]);
		argv[1] = tmp;
	}

	/* Initialise default values */
	tar_handle = init_handle();
	tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL;

	bb_opt_complementaly = "c~tx:t~cx:x~ct:X*:T*";
#ifdef CONFIG_FEATURE_TAR_LONG_OPTIONS
	bb_applet_long_options = tar_long_options;
#endif

	opt = bb_getopt_ulflags(argc, argv, tar_options,
				&base_dir,      /* Change to dir <optarg> */
				&tar_filename /* archive filename */
#ifdef CONFIG_FEATURE_TAR_FROM
				, NULL,
				&(tar_handle->reject)
#endif
				);

	/* Check one and only one context option was given */
	if(opt & 0x80000000UL) {
		bb_show_usage();
	}
#ifdef CONFIG_FEATURE_TAR_CREATE
	ctx_flag = opt & (CTX_CREATE | CTX_TEST | CTX_EXTRACT);
#else
	ctx_flag = opt & (CTX_TEST | CTX_EXTRACT);
#endif
	if (ctx_flag == 0) {
		bb_show_usage();
	}
	if(ctx_flag & CTX_TEST) {
		if ((tar_handle->action_header == header_list) ||
			(tar_handle->action_header == header_verbose_list)) {
			tar_handle->action_header = header_verbose_list;
		} else {
			tar_handle->action_header = header_list;
		}
	}
	if(ctx_flag & CTX_EXTRACT) {
		if (tar_handle->action_data != data_extract_to_stdout)
			tar_handle->action_data = data_extract_all;
		}
	if(opt & TAR_OPT_2STDOUT) {
		/* To stdout */
		tar_handle->action_data = data_extract_to_stdout;
	}
	if(opt & TAR_OPT_VERBOSE) {
		if ((tar_handle->action_header == header_list) ||
			(tar_handle->action_header == header_verbose_list))
		{
		tar_handle->action_header = header_verbose_list;
		} else {
			tar_handle->action_header = header_list;
		}
	}
	if (opt & TAR_OPT_KEEP_OLD) {
		tar_handle->flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL;
	}

#ifdef CONFIG_FEATURE_TAR_GZIP
	if(opt & TAR_OPT_GZIP) {
		get_header_ptr = get_header_tar_gz;
	}
#endif
#ifdef CONFIG_FEATURE_TAR_BZIP2
	if(opt & TAR_OPT_BZIP2) {
		get_header_ptr = get_header_tar_bz2;
	}
#endif
#ifdef CONFIG_FEATURE_TAR_COMPRESS
	if(opt & TAR_OPT_UNCOMPRESS) {
		get_header_ptr = get_header_tar_Z;
	}
#endif
#ifdef CONFIG_FEATURE_TAR_FROM
	if(opt & TAR_OPT_EXCLUDE_FROM) {
		tar_handle->reject = append_file_list_to_list(tar_handle->reject);
	}
#endif

	/* Check if we are reading from stdin */
	if ((argv[optind]) && (*argv[optind] == '-')) {
		/* Default is to read from stdin, so just skip to next arg */
		optind++;
	}

	/* Setup an array of filenames to work with */
	/* TODO: This is the same as in ar, separate function ? */
	while (optind < argc) {
		char *filename_ptr = last_char_is(argv[optind], '/');
		if (filename_ptr) {
			*filename_ptr = '\0';
		}
		tar_handle->accept = llist_add_to(tar_handle->accept, argv[optind]);
		optind++;
	}

	if ((tar_handle->accept) || (tar_handle->reject)) {
		tar_handle->filter = filter_accept_reject_list;
	}

	/* Open the tar file */
	{
		FILE *tar_stream;
		int flags;

#ifdef CONFIG_FEATURE_TAR_CREATE
		if (opt & CTX_CREATE) {
			/* Make sure there is at least one file to tar up.  */
			if (tar_handle->accept == NULL) {
				bb_error_msg_and_die("Cowardly refusing to create an empty archive");
			}
			tar_stream = stdout;
			flags = O_WRONLY | O_CREAT | O_EXCL;
			unlink(tar_filename);
		} else
#endif
		{
			tar_stream = stdin;
			flags = O_RDONLY;
		}

		if ((tar_filename[0] == '-') && (tar_filename[1] == '\0')) {
			tar_handle->src_fd = fileno(tar_stream);
			tar_handle->seek = seek_by_char;
		} else {
			tar_handle->src_fd = bb_xopen(tar_filename, flags);
		}
	}

	if ((base_dir) && (chdir(base_dir))) {
		bb_perror_msg_and_die("Couldnt chdir to %s", base_dir);
	}

#ifdef CONFIG_FEATURE_TAR_CREATE
	/* create an archive */
	if (opt & CTX_CREATE) {
		int verboseFlag = FALSE;
		int gzipFlag = FALSE;

# ifdef CONFIG_FEATURE_TAR_GZIP
		if (get_header_ptr == get_header_tar_gz) {
			gzipFlag = TRUE;
		}
# endif /* CONFIG_FEATURE_TAR_GZIP */
# ifdef CONFIG_FEATURE_TAR_BZIP2
		if (get_header_ptr == get_header_tar_bz2) {
			bb_error_msg_and_die("Creating bzip2 compressed archives is not currently supported.");
		}
# endif /* CONFIG_FEATURE_TAR_BZIP2 */

		if ((tar_handle->action_header == header_list) ||
				(tar_handle->action_header == header_verbose_list)) {
			verboseFlag = TRUE;
		}
		writeTarFile(tar_handle->src_fd, verboseFlag, opt & TAR_OPT_DEREFERNCE, tar_handle->accept,
			tar_handle->reject, gzipFlag);
	} else
#endif /* CONFIG_FEATURE_TAR_CREATE */
	{
		while (get_header_ptr(tar_handle) == EXIT_SUCCESS);

		/* Ckeck that every file that should have been extracted was */
		while (tar_handle->accept) {
			if (find_list_entry(tar_handle->reject, tar_handle->accept->data) == NULL) {
				if (find_list_entry(tar_handle->passed, tar_handle->accept->data) == NULL) {
					bb_error_msg_and_die("%s: Not found in archive\n", tar_handle->accept->data);
				}
			}
			tar_handle->accept = tar_handle->accept->link;
		}
	}

#ifdef CONFIG_FEATURE_CLEAN_UP
	if (tar_handle->src_fd != STDIN_FILENO) {
		close(tar_handle->src_fd);
	}
#endif /* CONFIG_FEATURE_CLEAN_UP */

	return(EXIT_SUCCESS);
}
int flash_eraseall_main(int argc, char **argv)
{
    struct jffs2_unknown_node oob_cleanmarker;
    mtd_info_t meminfo;
    int fd, clmpos, clmlen;
    erase_info_t erase;
    struct stat st;
    unsigned int flags;
    char *mtd_name;

//    flags = BBTEST | bb_getopt_ulflags(argc, argv, "jqre");
    flags = BBTEST | getopt32(argv,"jqre");

    mtd_name = argv[optind];

    stat(mtd_name, &st);
    if (!S_ISCHR(st.st_mode))
        bb_error_msg_and_die("%s: not a char device", mtd_name);

    fd = bb_xopen(mtd_name, O_RDWR);

    ioctl(fd, MEMGETINFO, &meminfo);
    erase.length = meminfo.erasesize;
    if (meminfo.type == MTD_NANDFLASH)
        flags |= IS_NAND;

    clmpos = 0;
    clmlen = 8;
    if (flags & OPTION_J) {

        oob_cleanmarker.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
        oob_cleanmarker.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
        oob_cleanmarker.totlen = cpu_to_je32(8);
        oob_cleanmarker.hdr_crc = cpu_to_je32(0);

        if (!(flags & IS_NAND))
            oob_cleanmarker.totlen = cpu_to_je32(sizeof(struct jffs2_unknown_node));
        else {
            struct k_nand_ecclayout ecclayout;

            ioctl(fd, ECCGETLAYOUT, &ecclayout);
            clmlen = ecclayout.oobavail;
            clmpos = 0;
        }
    }

    /* Don't want to destroy progress indicator by bb_error_msg's */
    printf("\nflash_eraseall: %s", mtd_name);

    for (erase.start = 0; erase.start < meminfo.size;
         erase.start += meminfo.erasesize) {
        if (flags & BBTEST) {
            int ret;
            loff_t offset = erase.start;

            ret = ioctl(fd, MEMGETBADBLOCK, &offset);
            if (ret > 0) {
                if (!(flags & OPTION_Q))
                    printf("\nSkipping bad block at 0x%08x", erase.start);
                continue;
            }
            if (ret < 0) {
                /* Black block table is not available on certain flash
                 * types e.g. NOR
                 */
                if (errno == EOPNOTSUPP) {
                    flags = ~BBTEST;
                    if (flags & IS_NAND)
                        bb_error_msg_and_die("bad block check not available");
                } else {
                    bb_perror_msg_and_die("MEMGETBADBLOCK error");
                }
            }
        }

        if (!(flags & OPTION_Q))
            show_progress(&meminfo, &erase);

        if (!(flags & OPTION_E))
            ioctl(fd, MEMERASE, &erase);

        /* format for JFFS2 ? */
        if (!(flags & OPTION_J))
            continue;

        /* write cleanmarker */
        if (flags & IS_NAND) {
            struct mtd_oob_buf oob;

            oob.ptr = (unsigned char *) &oob_cleanmarker;
            oob.start = erase.start + clmpos;
            oob.length = clmlen;
#if 0 /* TESTING */
            printf("W %8.8lx %lu - %8.8lx %8.8lx %8.8lx\n",
                (unsigned long) oob.start, (unsigned long) oob.length,
                *((unsigned long *) &oob_cleanmarker + 0),
                *((unsigned long *) &oob_cleanmarker + 1),
                *((unsigned long *) &oob_cleanmarker + 2));
#endif
            ioctl(fd, MEMWRITEOOB, &oob);
        } else {
            lseek(fd, erase.start, SEEK_SET);
            /* if (lseek(fd, erase.start, SEEK_SET) < 0) {
                bb_perror_msg("MTD %s failure", "seek");
                continue;
            } */
            write(fd, &oob_cleanmarker, sizeof(oob_cleanmarker));
            /* if (write(fd, &oob_cleanmarker, sizeof(oob_cleanmarker)) != sizeof(oob_cleanmarker)) {
                bb_perror_msg("MTD %s failure", "write");
                continue;
            } */
        }
        if (!(flags & OPTION_Q))
            printf(" Cleanmarker written at %x.", erase.start);
    }
    if (!(flags & OPTION_Q)) {
        show_progress(&meminfo, &erase);
        putchar('\n');
    }

    if (flags & OPTION_R) {
        int i;
        /* For testing, read back cleanmarker plus 12 bytes. */
        for (i= 0; i< meminfo.size; i+= meminfo.erasesize) { 
            if (flags & BBTEST) {
                int ret;
                loff_t offset = i;

                ret = ioctl(fd, MEMGETBADBLOCK, &offset);
                if (ret > 0) {
                    if (!(flags & OPTION_Q))
                        printf("\nSkipping bad block at 0x%08x", i);
                    continue;
                }
                if (ret < 0) {
                    /* Black block table is not available on certain flash
                     * types e.g. NOR
                     */
                    if (errno == EOPNOTSUPP) {
                        flags = ~BBTEST;
                        if (flags & IS_NAND)
                            bb_error_msg_and_die("bad block check not available");
                    } else {
                        bb_perror_msg_and_die("MEMGETBADBLOCK error");
                    }
                }
            }

            if (flags & IS_NAND) {
                unsigned char clnmrk[20];
                struct mtd_oob_buf oob;

                memset(clnmrk, 0x00, sizeof(clnmrk));
                oob.ptr = (unsigned char *) &clnmrk;
                oob.start = i + clmpos;
                oob.length = 16; // clmlen;
                ioctl(fd, MEMREADOOB, &oob);

                printf("R %8.8lx %lu - %8.8lx %8.8lx %8.8lx %8.8lx\n",
                    (unsigned long) (i + clmpos),
                    (unsigned long) clmlen,
                    *((unsigned long *) &clnmrk[0]),
                    *((unsigned long *) &clnmrk[4]),
                    *((unsigned long *) &clnmrk[8]),
                    *((unsigned long *) &clnmrk[12]));
            }
        }
    }

    close(fd);
    return EXIT_SUCCESS;
}
Beispiel #3
0
int readprofile_main(int argc, char **argv)
{
	FILE *map;
	int proFd;
	const char *mapFile, *proFile, *mult=0;
	unsigned long len=0, indx=1;
	unsigned long long add0=0;
	unsigned int step;
	unsigned int *buf, total, fn_len;
	unsigned long long fn_add, next_add;          /* current and next address */
	char fn_name[S_LEN], next_name[S_LEN];   /* current and next name */
	char mode[8];
	int c;
	int optAll=0, optInfo=0, optReset=0, optVerbose=0, optNative=0;
	int optBins=0, optSub=0;
	char mapline[S_LEN];
	int maplineno=1;
	int header_printed;

#define next (current^1)

	proFile = defaultpro;
	mapFile = defaultmap;

	while ((c = getopt(argc, argv, "M:m:np:itvarVbs")) != -1) {
		switch(c) {
		case 'm':
			mapFile = optarg;
			break;
		case 'n':
			optNative++;
			break;
		case 'p':
			proFile = optarg;
			break;
		case 'a':
			optAll++;
			break;
		case 'b':
			optBins++;
			break;
		case 's':
			optSub++;
			break;
		case 'i':
			optInfo++;
			break;
		case 'M':
			mult = optarg;
			break;
		case 'r':
			optReset++;
			break;
		case 'v':
			optVerbose++;
			break;
		default:
			bb_show_usage();
		}
	}

	if (optReset || mult) {
		int multiplier, fd, to_write;

		/*
		 * When writing the multiplier, if the length of the write is
		 * not sizeof(int), the multiplier is not changed
		 */
		if (mult) {
			multiplier = strtoul(mult, 0, 10);
			to_write = sizeof(int);
		} else {
			multiplier = 0;
			to_write = 1;	/* sth different from sizeof(int) */
		}

		fd = bb_xopen(defaultpro,O_WRONLY);

		if (write(fd, &multiplier, to_write) != to_write)
			bb_perror_msg_and_die("error writing %s", defaultpro);

		close(fd);
		return EXIT_SUCCESS;
	}

	/*
	 * Use an fd for the profiling buffer, to skip stdio overhead
	 */
	 
	proFd = bb_xopen(proFile,O_RDONLY);
	
	if (((int)(len=lseek(proFd,0,SEEK_END)) < 0)
	    || (lseek(proFd,0,SEEK_SET) < 0))
		bb_perror_msg_and_die(proFile);

	buf = xmalloc(len);

	if (read(proFd,buf,len) != len)
		bb_perror_msg_and_die(proFile);

	close(proFd);

	if (!optNative) {
		int entries = len/sizeof(*buf);
		int big = 0,small = 0,i;
		unsigned *p;

		for (p = buf+1; p < buf+entries; p++) {
			if (*p & ~0U << (sizeof(*buf)*4))
				big++;
			if (*p & ((1 << (sizeof(*buf)*4))-1))
				small++;
		}
		if (big > small) {
			bb_error_msg("Assuming reversed byte order. "
				"Use -n to force native byte order.");
			for (p = buf; p < buf+entries; p++)
				for (i = 0; i < sizeof(*buf)/2; i++) {
					unsigned char *b = (unsigned char *) p;
					unsigned char tmp;

					tmp = b[i];
					b[i] = b[sizeof(*buf)-i-1];
					b[sizeof(*buf)-i-1] = tmp;
				}
		}
	}

	step = buf[0];
	if (optInfo) {
		printf("Sampling_step: %i\n", step);
		return EXIT_SUCCESS;
	}

	total = 0;

	map = bb_xfopen(mapFile, "r");

	while (fgets(mapline,S_LEN,map)) {
		if (sscanf(mapline,"%llx %s %s",&fn_add,mode,fn_name) != 3)
			bb_error_msg_and_die("%s(%i): wrong map line",
					     mapFile, maplineno);

		if (!strcmp(fn_name,"_stext")) /* only elf works like this */ {
			add0 = fn_add;
			break;
		}
		maplineno++;
	}

	if (!add0)
		bb_error_msg_and_die("can't find \"_stext\" in %s", mapFile);

	/*
	 * Main loop.
	 */
	while (fgets(mapline,S_LEN,map)) {
		unsigned int this = 0;

		if (sscanf(mapline,"%llx %s %s",&next_add,mode,next_name) != 3)
			bb_error_msg_and_die("%s(%i): wrong map line",
					     mapFile, maplineno);

		header_printed = 0;

		/* ignore any LEADING (before a '[tT]' symbol is found)
		   Absolute symbols */
		if ((*mode == 'A' || *mode == '?') && total == 0) continue;
		if (*mode != 'T' && *mode != 't' &&
		    *mode != 'W' && *mode != 'w')
			break;	/* only text is profiled */

		if (indx >= len / sizeof(*buf))
			bb_error_msg_and_die("profile address out of range. "
					     "Wrong map file?");

		while (indx < (next_add-add0)/step) {
			if (optBins && (buf[indx] || optAll)) {
				if (!header_printed) {
					printf ("%s:\n", fn_name);
					header_printed = 1;
				}
				printf ("\t%llx\t%u\n", (indx - 1)*step + add0, buf[indx]);
			}
			this += buf[indx++];
		}
		total += this;

		if (optBins) {
			if (optVerbose || this > 0)
				printf ("  total\t\t\t\t%u\n", this);
		} else if ((this || optAll) &&
			   (fn_len = next_add-fn_add) != 0) {
			if (optVerbose)
				printf("%016llx %-40s %6i %8.4f\n", fn_add,
				       fn_name,this,this/(double)fn_len);
			else
				printf("%6i %-40s %8.4f\n",
				       this,fn_name,this/(double)fn_len);
			if (optSub) {
				unsigned long long scan;

				for (scan = (fn_add-add0)/step + 1;
				     scan < (next_add-add0)/step; scan++) {
					unsigned long long addr;

					addr = (scan - 1)*step + add0;
					printf("\t%#llx\t%s+%#llx\t%u\n",
					       addr, fn_name, addr - fn_add,
					       buf[scan]);
				}
			}
		}

		fn_add = next_add;
		strcpy(fn_name,next_name);

		maplineno++;
	}

	/* clock ticks, out of kernel text - probably modules */
	printf("%6i %s\n", buf[len/sizeof(*buf)-1], "*unknown*");

	/* trailer */
	if (optVerbose)
		printf("%016x %-40s %6i %8.4f\n",
		       0,"total",total,total/(double)(fn_add-add0));
	else
		printf("%6i %-40s %8.4f\n",
		       total,"total",total/(double)(fn_add-add0));

	fclose(map);
	free(buf);

	return EXIT_SUCCESS;
}
Beispiel #4
0
extern int gunzip_main(int argc, char **argv)
{
	char status = EXIT_SUCCESS;
	unsigned long opt;

	opt = bb_getopt_ulflags(argc, argv, "cftd");
	/* if called as zcat */
	if (strcmp(bb_applet_name, "zcat") == 0) {
		opt |= GUNZIP_OPT_STDOUT;
	}

	do {
		struct stat stat_buf;
		const char *old_path = argv[optind];
		const char *delete_path = NULL;
		char *new_path = NULL;
		int src_fd;
		int dst_fd;

		optind++;

		if (old_path == NULL || strcmp(old_path, "-") == 0) {
			src_fd = STDIN_FILENO;
			opt |= GUNZIP_OPT_STDOUT;
		} else {
			src_fd = bb_xopen(old_path, O_RDONLY);

			/* Get the time stamp on the input file. */
			if (stat(old_path, &stat_buf) < 0) {
				bb_error_msg_and_die("Couldn't stat file %s", old_path);
			}
		}

		/* Check that the input is sane.  */
		if (isatty(src_fd) && ((opt & GUNZIP_OPT_FORCE) == 0)) {
			bb_error_msg_and_die
				("compressed data not read from terminal.  Use -f to force it.");
		}

		/* Set output filename and number */
		if (opt & GUNZIP_OPT_TEST) {
			dst_fd = bb_xopen(bb_dev_null, O_WRONLY);	/* why does test use filenum 2 ? */
		} else if (opt & GUNZIP_OPT_STDOUT) {
			dst_fd = STDOUT_FILENO;
		} else {
			char *extension;

			new_path = bb_xstrdup(old_path);

			extension = strrchr(new_path, '.');
#ifdef CONFIG_FEATURE_GUNZIP_UNCOMPRESS
			if (extension && (strcmp(extension, ".Z") == 0)) {
				*extension = '\0';
			} else
#endif
			if (extension && (strcmp(extension, ".gz") == 0)) {
				*extension = '\0';
			} else if (extension && (strcmp(extension, ".tgz") == 0)) {
				extension[2] = 'a';
				extension[3] = 'r';
			} else {
				bb_error_msg_and_die("Invalid extension");
			}

			/* Open output file */
			dst_fd = bb_xopen(new_path, O_WRONLY | O_CREAT);

			/* Set permissions on the file */
			chmod(new_path, stat_buf.st_mode);

			/* If unzip succeeds remove the old file */
			delete_path = old_path;
		}

		/* do the decompression, and cleanup */
		if (bb_xread_char(src_fd) == 0x1f) {
			unsigned char magic2;

			magic2 = bb_xread_char(src_fd);
#ifdef CONFIG_FEATURE_GUNZIP_UNCOMPRESS
			if (magic2 == 0x9d) {
				status = uncompress(src_fd, dst_fd);
			} else
#endif
				if (magic2 == 0x8b) {
					check_header_gzip(src_fd);
					status = inflate_gunzip(src_fd, dst_fd);
					if (status != 0) {
						bb_error_msg_and_die("Error inflating");
					}
				} else {
					bb_error_msg_and_die("Invalid magic");
				}
		} else {
			bb_error_msg_and_die("Invalid magic");
		}

		if ((status != EXIT_SUCCESS) && (new_path)) {
			/* Unzip failed, remove new path instead of old path */
			delete_path = new_path;
		}

		if (dst_fd != STDOUT_FILENO) {
			close(dst_fd);
		}
		if (src_fd != STDIN_FILENO) {
			close(src_fd);
		}

		/* delete_path will be NULL if in test mode or from stdin */
		if (delete_path && (unlink(delete_path) == -1)) {
			bb_error_msg_and_die("Couldn't remove %s", delete_path);
		}

		free(new_path);

	} while (optind < argc);

	return status;
}
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) {
		bb_error_msg_and_die("PASV error: %s", buf + 4);
	}
	fd_data = xconnect_ftpdata(server, buf);

	if (ftpcmd("CWD ", server_path, control_stream, buf) != 250) {
		bb_error_msg_and_die("CWD error: %s", buf + 4);
	}

	/* get the local file */
	if ((local_path[0] == '-') && (local_path[1] == '\0')) {
		fd_local = fileno(stdin);
	} else {
		fd_local = bb_xopen(local_path, O_RDONLY);
		fstat(fd_local, &sbuf);

		sprintf(buf, "ALLO %lu", (unsigned long)sbuf.st_size);
		response = ftpcmd(buf, NULL, control_stream, buf);
		switch (response) {
		case 200:
		case 202:
			break;
		default:
			close(fd_local);
			bb_error_msg_and_die("ALLO error: %s", buf + 4);
			break;
		}
	}
	response = ftpcmd("STOR ", local_path, control_stream, buf);
	switch (response) {
	case 125:
	case 150:
		break;
	default:
		close(fd_local);
		bb_error_msg_and_die("STOR error: %s", buf + 4);
	}

	/* 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) {
		bb_error_msg_and_die("error: %s", buf + 4);
	}
	ftpcmd("QUIT", NULL, control_stream, buf);

	return(EXIT_SUCCESS);
}
static int ftp_recieve(ftp_host_info_t *server, FILE *control_stream, 
		const char *local_path, char *server_path)
{
	char buf[512];
	off_t filesize = 0;
	int fd_data;
	int fd_local = -1;
	off_t beg_range = 0;

	/* Connect to the data socket */
	if (ftpcmd("PASV", NULL, control_stream, buf) != 227) {
		bb_error_msg_and_die("PASV error: %s", buf + 4);
	}
	fd_data = xconnect_ftpdata(server, buf);

	if (ftpcmd("SIZE ", server_path, control_stream, buf) == 213) {
		filesize = atol(buf + 4);
	}

	if ((local_path[0] == '-') && (local_path[1] == '\0')) {
		fd_local = fileno(stdout);
		do_continue = 0;
	}

	if (do_continue) {
		struct stat sbuf;
		if (lstat(local_path, &sbuf) < 0) {
			bb_perror_msg_and_die("fstat()");
		}
		if (sbuf.st_size > 0) {
			beg_range = sbuf.st_size;
		} else {
			do_continue = 0;
		}
	}

	if (do_continue) {
		sprintf(buf, "REST %ld", (long)beg_range);
		if (ftpcmd(buf, NULL, control_stream, buf) != 350) {
			do_continue = 0;
		} else {
			filesize -= beg_range;
		}
	}

	if (ftpcmd("RETR ", server_path, control_stream, buf) > 150) {
		bb_error_msg_and_die("RETR error: %s", buf + 4);
	}

	/* only make a local file if we know that one exists on the remote server */
	if (fd_local == -1) {
		if (do_continue) {
			fd_local = bb_xopen(local_path, O_APPEND | O_WRONLY);
		} else {
			fd_local = bb_xopen(local_path, O_CREAT | O_TRUNC | O_WRONLY);
		}
	}

	/* Copy the file */
	if (bb_copyfd_size(fd_data, fd_local, filesize) == -1) {
		exit(EXIT_FAILURE);
	}

	/* close it all down */
	close(fd_data);
	if (ftpcmd(NULL, NULL, control_stream, buf) != 226) {
		bb_error_msg_and_die("ftp error: %s", buf + 4);
	}
	ftpcmd("QUIT", NULL, control_stream, buf);
	
	return(EXIT_SUCCESS);
}
Beispiel #7
0
int dd_main(int argc, char **argv)
{
	size_t out_full = 0;
	size_t out_part = 0;
	size_t in_full = 0;
	size_t in_part = 0;
	size_t count = -1;
	size_t bs = 512;
	ssize_t n;
	off_t seek = 0;
	off_t skip = 0;
	int sync_flag = FALSE;
	int noerror = FALSE;
	int trunc_flag = TRUE;
	int oflag;
	int ifd;
	int ofd;
	int i;
	const char *infile = NULL;
	const char *outfile = NULL;
	char *buf;

	for (i = 1; i < argc; i++) {
		if (strncmp("bs=", argv[i], 3) == 0)
			bs = bb_xparse_number(argv[i]+3, dd_suffixes);
		else if (strncmp("count=", argv[i], 6) == 0)
			count = bb_xparse_number(argv[i]+6, dd_suffixes);
		else if (strncmp("seek=", argv[i], 5) == 0)
			seek = bb_xparse_number(argv[i]+5, dd_suffixes);
		else if (strncmp("skip=", argv[i], 5) == 0)
			skip = bb_xparse_number(argv[i]+5, dd_suffixes);
		else if (strncmp("if=", argv[i], 3) == 0)
			infile = argv[i]+3;
		else if (strncmp("of=", argv[i], 3) == 0)
			outfile = argv[i]+3;
		else if (strncmp("conv=", argv[i], 5) == 0) {
			buf = argv[i]+5;
			while (1) {
				if (strncmp("notrunc", buf, 7) == 0) {
					trunc_flag = FALSE;
					buf += 7;
				} else if (strncmp("sync", buf, 4) == 0) {
					sync_flag = TRUE;
					buf += 4;
				} else if (strncmp("noerror", buf, 7) == 0) {
					noerror = TRUE;
					buf += 7;
				} else {
					bb_error_msg_and_die("invalid conversion `%s'", argv[i]+5);
				}
				if (buf[0] == '\0')
					break;
				if (buf[0] == ',')
					buf++;
			}
		} else
			bb_show_usage();
	}

	buf = xmalloc(bs);

	if (infile != NULL) {
		ifd = bb_xopen(infile, O_RDONLY|0x20000000);
	} else {
		ifd = STDIN_FILENO;
		infile = bb_msg_standard_input;
	}

	if (outfile != NULL) {
		oflag = O_WRONLY | O_CREAT;

		if (!seek && trunc_flag) {
			oflag |= O_TRUNC;
		}

		if ((ofd = open(outfile, oflag|0x20000000, 0666)) < 0) {
			bb_perror_msg_and_die("%s", outfile);
		}

		if (seek && trunc_flag) {
			if (ftruncate(ofd, seek * bs) < 0) {
				struct stat st;

				if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) ||
						S_ISDIR (st.st_mode)) {
					bb_perror_msg_and_die("%s", outfile);
				}
			}
		}
	} else {
		ofd = STDOUT_FILENO;
		outfile = bb_msg_standard_output;
	}

	if (skip) {
		if (lseek(ifd, skip * bs, SEEK_CUR) < 0) {
			bb_perror_msg_and_die("%s", infile);
		}
	}

	if (seek) {
		if (lseek(ofd, seek * bs, SEEK_CUR) < 0) {
			bb_perror_msg_and_die("%s", outfile);
		}
	}

	while (in_full + in_part != count) {
		if (noerror) {
			/* Pre-zero the buffer when doing the noerror thing */
			memset(buf, '\0', bs);
		}
		n = safe_read(ifd, buf, bs);
		if (n < 0) {
			if (noerror) {
				n = bs;
				bb_perror_msg("%s", infile);
			} else {
				bb_perror_msg_and_die("%s", infile);
			}
		}
		if (n == 0) {
			break;
		}
		if ((size_t)n == bs) {
			in_full++;
		} else {
			in_part++;
		}
		if (sync_flag) {
			memset(buf + n, '\0', bs - n);
			n = bs;
		}
		n = bb_full_write(ofd, buf, n);
		if (n < 0) {
			bb_perror_msg_and_die("%s", outfile);
		}
		if ((size_t)n == bs) {
			out_full++;
		} else {
			out_part++;
		}
	}

	if (close (ifd) < 0) {
		bb_perror_msg_and_die("%s", infile);
	}

	if (close (ofd) < 0) {
		bb_perror_msg_and_die("%s", outfile);
	}

	fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n",
			(long)in_full, (long)in_part,
			(long)out_full, (long)out_part);

	return EXIT_SUCCESS;
}