|
本程序使用wget下载一批量的URL,最多进程数为5个.
用法:
- mdown http://www.abc.com/track/track[001-2].mp3
复制代码
将下载:
http://www.abc.com/track/track001.mp3
http://www.abc.com/track/track002.mp3
等文件,GPL发布,希望对你有用.
对fork(), execve()和信号没懂的朋友也是一个帮助.
Mdown.c
- /* Author: liquid_zigong@www.linuxsir.cn */
- #include<stdio.h>
- #include<string.h>
- #include<stdlib.h>
- #include<signal.h>
- #include<unistd.h>
- /* 最大进程数 */
- #define MAXPROC 5
- /* 下载工具的位置 */
- #define PROG "/usr/bin/wget"
- /* 临时文件记录名前缀 */
- #define TMPPREF "/tmp/.moviedownloader"
- void cleanup(void);
- void sig_cleanup(int sig);
- int usage(int argc, char* argv[]);
- int url2file(char* outfile, char *url);
- int start_download_proc(char *outfile, int maxproc);
- int detail_info(char *outfile);
- int main(int argc, char *argv[])
- {
- char outfile[80];
- if(argc < 2) {
- usage(argc, argv);
- exit(1);
- }
- /*注册退出时清理函数*/
- atexit(&cleanup);
- signal(SIGINT, &sig_cleanup);
-
- sprintf(outfile, "%s%d", TMPPREF, getpid());
- url2file(outfile, argv[1]);
- detail_info(outfile);
- start_download_proc(outfile, MAXPROC);
- return 0;
- }
- int usage(int argc, char* argv[])
- {
- fprintf(stderr, "%s: url[start-end]\n", argv[0]);
- return 0;
- }
- /*把转换后的URL写入outfile*/
- int url2file(char* outfile, char *url)
- {
- char prefix[BUFSIZ], suffix[BUFSIZ], fmt[40], *p;
- FILE *fp;
- int start, end, zerocnt = 0, i;
- fp = fopen(outfile, "w");
- if(!fp) {
- perror("url2file");
- exit(1);
- }
-
- if((p=strchr(url, '[')) == NULL) {
- fclose(fp);
- fprintf(stderr, "Bad URL assigned\n");
- exit(1);
- }
-
- if((p=strchr(p, '-')) == NULL) {
- fclose(fp);
- fprintf(stderr, "Bad URL assigned\n");
- exit(1);
- }
-
- if((p=strchr(p, ']')) == NULL) {
- fclose(fp);
- fprintf(stderr, "Bad URL assigned\n");
- exit(1);
- }
- p = strchr(url, '[');
- p++;
- while(*p == '0') {
- p++;
- zerocnt ++;
- }
- p = strchr(url, '[');
- start = atoi(p+1);
- p = strchr(p, '-');
- end = atoi(p+1);
-
- strncpy(prefix, url, strchr(url, '[') - url);
- p = strchr(strchr(url, '['), ']');
- p++;
- strcpy(suffix, p);
-
- sprintf(fmt, "%%s%%0%dd%%s\n", zerocnt+1);
- for(i = start; i <= end; i++) {
- fprintf(fp, fmt, prefix, i, suffix);
- }
-
- fclose(fp);
- return 1;
- }
- /*开maxproc个进程同时下载*/
- int start_download_proc(char *outfile, int maxproc)
- {
- int result;
- int proc = 0;
- pid_t pid;
- FILE *fp, *logger;
- char line[BUFSIZ], *argv[] = {
- PROG, /* 第一个参数 */
- line, /* 第二个参数 */
- NULL /* 这是参数的结束,必须的 */
- };
- if((fp = fopen(outfile, "r")) == NULL) {
- perror("start_download_proc");
- exit(1);
- }
-
- while(fgets(line, sizeof(line), fp) != NULL) {
- /* fgets() 会在字符串后加上个'\n',删掉它 */
- line[strlen(line) - 1] = '\0';
- pid = fork();
- if(pid < 0) {
- perror("fork");
- exit(1);
- }
- if(pid == 0) {
- /* 关闭STDIN_FILENO和STDOUT_FILENO */
- /* 这样就看不到wget终端输出
- close(0);
- close(1);
- /* close(2); */
-
- execve(PROG, argv, NULL);
- abort();
- }
- proc++;
- if(proc == maxproc) {
- wait(&result);
- printf("A download finished\n");
- proc--;
- }
- }
- /*如果还有没下载完的*/
- printf("All task assigned, waiting for children\n");
- while(proc != 0) {
- wait(&result);
- proc --;
- }
-
- printf("All downloads finisned\n");
- return 1;
- }
- /*用户按下Ctrl-C键时,清理文件*/
- void sig_cleanup(int sig)
- {
- char filename[20];
- sprintf(filename , "%s%d", TMPPREF, getpid());
- unlink(filename);
- exit(0);
- }
- /*正常退出时清理文件*/
- void cleanup(void)
- {
- char filename[20];
- sprintf(filename , "%s%d", TMPPREF, getpid());
- unlink(filename);
- }
- /*显示下载文件细节*/
- int detail_info(char *outfile)
- {
- FILE *fp;
- char line[BUFSIZ];
-
- if((fp = fopen(outfile, "r")) == NULL) {
- perror("detail_inf");
- exit(0);
- }
-
- printf("Going to download:\n");
- while(fgets(line, sizeof(line), fp) != NULL) {
- printf("%s", line);
- }
- printf("\n");
- return sleep(1);
- }
复制代码 |
|