Loading man/feh.pre +5 −8 Original line number Diff line number Diff line Loading @@ -116,10 +116,6 @@ Zoom pictures to screen size in fullscreen .It Cm -x , --borderless Create borderless windows. . .It Cm -Q , --builtin Use builtin HTTP client to grab remote files instead of .Xr wget 1 . . .It Cm -P , --cache-thumbnails Enable (experimental) thumbnail caching in .Pa ~/.thumbnails . Loading Loading @@ -993,10 +989,11 @@ binary .Pq usually distributed in Qo libjpeg-progs Qc or similar for lossless rotation. .Pp To view images from URLs such as http://, you need to have .Cm wget available or use the builtin HTTP client .Pq see Cm --builtin . To view images from URLs such as http://, you need .Nm compiled with libcurl support (enabled by default). See the .Sx VERSION section. . . .Sh BUGS Loading src/help.raw +0 −2 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ OPTIONS -D, --slideshow-delay NUM Set delay between automatically changing slides --cycle-once Exit after one loop through the slideshow -R, --reload NUM Reload images after NUM seconds -Q, --builtin Use builtin http client instead of wget -k, --keep-http Keep local copies when viewing HTTP/FTP files -K, --caption-path PATH Path to caption directory, enables caption display -j, --output-dir With -k: Output directory for saved files Loading @@ -49,7 +48,6 @@ OPTIONS -A, --action ACTION Specify action to perform when pressing <return>. Executed by /bin/sh, may contain FORMAT SPECIFIERS --action[1-9] Extra actions triggered by pressing keys <1>to <9> --action-hold-slide Do not change to next image after running an action -G, --draw-actions Show the defined actions in the image window -m, --montage Enable montage mode -c, --collage Montage mode with randomly distributed thumbnails Loading src/imlib.c +55 −242 Original line number Diff line number Diff line Loading @@ -233,8 +233,16 @@ int feh_load_image(Imlib_Image * im, feh_file * file) return(1); } #ifdef HAVE_LIBCURL char *feh_http_load_image(char *url) { CURL *curl; CURLcode res; char *sfn; FILE *sfp; int fd = -1; char *ebuff; char *tmpname; char *basename; char *path = NULL; Loading @@ -250,205 +258,6 @@ char *feh_http_load_image(char *url) basename = strrchr(url, '/') + 1; tmpname = feh_unique_filename(path, basename); if (opt.builtin_http) { /* state for HTTP header parser */ #define SAW_NONE 1 #define SAW_ONE_CM 2 #define SAW_ONE_CJ 3 #define SAW_TWO_CM 4 #define IN_BODY 5 #define OUR_BUF_SIZE 1024 #define EOL "\015\012" int sockno = 0; int size; int body = SAW_NONE; struct addrinfo hints; struct addrinfo *result, *rp; char *hostname; char *get_string; char *host_string; char *query_string; char *get_url; static char buf[OUR_BUF_SIZE]; char ua_string[] = "User-Agent: feh image viewer"; char accept_string[] = "Accept: image/*"; FILE *fp; D(("using builtin http collection\n")); fp = fopen(tmpname, "w"); if (!fp) { weprintf("couldn't write to file %s:", tmpname); free(tmpname); return(NULL); } hostname = feh_strip_hostname(url); if (!hostname) { weprintf("couldn't work out hostname from %s:", url); fclose(fp); unlink(tmpname); free(tmpname); return(NULL); } D(("trying hostname %s\n", hostname)); memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICSERV; hints.ai_protocol = 0; if (getaddrinfo(hostname, "80", &hints, &result) != 0) { weprintf("error resolving host %s:", hostname); fclose(fp); unlink(tmpname); free(hostname); free(tmpname); return(NULL); } for (rp = result; rp != NULL; rp = rp->ai_next) { sockno = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sockno == -1) { continue; } if (connect(sockno, rp->ai_addr, rp->ai_addrlen) != -1) { break; } close(sockno); } if (rp == NULL) { weprintf("error connecting socket:"); freeaddrinfo(result); fclose(fp); unlink(tmpname); free(tmpname); free(hostname); return(NULL); } freeaddrinfo(result); get_url = strchr(url, '/') + 2; get_url = strchr(get_url, '/'); get_string = estrjoin(" ", "GET", get_url, "HTTP/1.0", NULL); host_string = estrjoin(" ", "Host:", hostname, NULL); query_string = estrjoin(EOL, get_string, host_string, accept_string, ua_string, "", "", NULL); /* At this point query_string looks something like ** ** GET /dir/foo.jpg?123456 HTTP/1.0^M^J ** Host: www.example.com^M^J ** Accept: image/ *^M^J ** User-Agent: feh image viewer^M^J ** ^M^J ** ** Host: is required by HTTP/1.1 and very important for some sites, ** even with HTTP/1.0 ** ** -- BEG */ if ((send(sockno, query_string, strlen(query_string), 0)) == -1) { free(get_string); free(host_string); free(query_string); free(tmpname); free(hostname); weprintf("error sending over socket:"); return(NULL); } free(get_string); free(host_string); free(query_string); free(hostname); while ((size = read(sockno, &buf, OUR_BUF_SIZE))) { if (body == IN_BODY) { fwrite(buf, 1, size, fp); } else { int i; for (i = 0; i < size; i++) { /* We are looking for ^M^J^M^J, but will accept ** ^J^J from broken servers. Stray ^Ms will be ** ignored. ** ** TODO: ** Checking the headers for a ** Content-Type: image/ * ** header would help detect problems with results. ** Maybe look at the response code too? But there is ** no fundamental reason why a 4xx or 5xx response ** could not return an image, it is just the 3xx ** series we need to worry about. ** ** Also, grabbing the size from the Content-Length ** header and killing the connection after that ** many bytes where read would speed up closing the ** socket. ** -- BEG */ switch (body) { case IN_BODY: fwrite(buf + i, 1, size - i, fp); i = size; break; case SAW_ONE_CM: if (buf[i] == '\012') { body = SAW_ONE_CJ; } else { body = SAW_NONE; } break; case SAW_ONE_CJ: if (buf[i] == '\015') { body = SAW_TWO_CM; } else { if (buf[i] == '\012') { body = IN_BODY; } else { body = SAW_NONE; } } break; case SAW_TWO_CM: if (buf[i] == '\012') { body = IN_BODY; } else { body = SAW_NONE; } break; case SAW_NONE: if (buf[i] == '\015') { body = SAW_ONE_CM; } else { if (buf[i] == '\012') { body = SAW_ONE_CJ; } } break; } /* switch */ } /* for i */ } } /* while read */ close(sockno); fclose(fp); #ifdef HAVE_LIBCURL } else { CURL *curl; CURLcode res; char *sfn; FILE *sfp; int fd = -1; char *ebuff; curl = curl_easy_init(); if (!curl) { weprintf("open url: libcurl initialization failure"); Loading Loading @@ -493,15 +302,19 @@ char *feh_http_load_image(char *url) curl_easy_cleanup(curl); return NULL; } #else } else { weprintf("Please compile feh with curl=1 to enable http support"); #else /* HAVE_LIBCURL */ char *feh_http_load_image(char *url) { weprintf( "Cannot load image %s\n Please recompile with libcurl support", url ); return NULL; } #endif return(tmpname); } #endif /* HAVE_LIBCURL */ char *feh_strip_hostname(char *url) { Loading src/options.c +1 −7 Original line number Diff line number Diff line Loading @@ -81,8 +81,6 @@ void init_parse_options(int argc, char **argv) opt.start_list_at = NULL; opt.jump_on_resort = 1; opt.builtin_http = 0; opt.xinerama = 0; opt.screen_clip = 1; #ifdef HAVE_LIBXINERAMA Loading Loading @@ -324,7 +322,7 @@ static void feh_getopt_theme(int argc, char **argv) static void feh_parse_option_array(int argc, char **argv) { static char stropts[] = "a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:J:kK:lL:mM:nNo:O:pPqQrR:sS:tT:uUvVwW:xXy:YzZ" "a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:J:kK:lL:mM:nNo:O:pPqrR:sS:tT:uUvVwW:xXy:YzZ" "0:1:2:4:5:8:9:.@:^:~:):|:+:"; /* (*name, has_arg, *flag, val) See: struct option in getopts.h */ Loading Loading @@ -355,7 +353,6 @@ static void feh_parse_option_array(int argc, char **argv) {"preload" , 0, 0, 'p'}, {"reverse" , 0, 0, 'n'}, {"thumbnails" , 0, 0, 't'}, {"builtin" , 0, 0, 'Q'}, {"scale-down" , 0, 0, '.'}, {"no-jump-on-resort", 0, 0, 220}, {"hide-pointer" , 0, 0, 'Y'}, Loading Loading @@ -470,9 +467,6 @@ static void feh_parse_option_array(int argc, char **argv) opt.list = 1; opt.display = 0; break; case 'Q': opt.builtin_http = 1; break; case 'L': opt.customlist = estrdup(optarg); opt.display = 0; Loading src/options.h +0 −2 Original line number Diff line number Diff line Loading @@ -63,8 +63,6 @@ struct __fehoptions { unsigned char reverse; unsigned char no_menus; unsigned char scale_down; unsigned char builtin_http; unsigned char libcurl_http; unsigned char bgmode; unsigned char xinerama; unsigned char screen_clip; Loading Loading
man/feh.pre +5 −8 Original line number Diff line number Diff line Loading @@ -116,10 +116,6 @@ Zoom pictures to screen size in fullscreen .It Cm -x , --borderless Create borderless windows. . .It Cm -Q , --builtin Use builtin HTTP client to grab remote files instead of .Xr wget 1 . . .It Cm -P , --cache-thumbnails Enable (experimental) thumbnail caching in .Pa ~/.thumbnails . Loading Loading @@ -993,10 +989,11 @@ binary .Pq usually distributed in Qo libjpeg-progs Qc or similar for lossless rotation. .Pp To view images from URLs such as http://, you need to have .Cm wget available or use the builtin HTTP client .Pq see Cm --builtin . To view images from URLs such as http://, you need .Nm compiled with libcurl support (enabled by default). See the .Sx VERSION section. . . .Sh BUGS Loading
src/help.raw +0 −2 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ OPTIONS -D, --slideshow-delay NUM Set delay between automatically changing slides --cycle-once Exit after one loop through the slideshow -R, --reload NUM Reload images after NUM seconds -Q, --builtin Use builtin http client instead of wget -k, --keep-http Keep local copies when viewing HTTP/FTP files -K, --caption-path PATH Path to caption directory, enables caption display -j, --output-dir With -k: Output directory for saved files Loading @@ -49,7 +48,6 @@ OPTIONS -A, --action ACTION Specify action to perform when pressing <return>. Executed by /bin/sh, may contain FORMAT SPECIFIERS --action[1-9] Extra actions triggered by pressing keys <1>to <9> --action-hold-slide Do not change to next image after running an action -G, --draw-actions Show the defined actions in the image window -m, --montage Enable montage mode -c, --collage Montage mode with randomly distributed thumbnails Loading
src/imlib.c +55 −242 Original line number Diff line number Diff line Loading @@ -233,8 +233,16 @@ int feh_load_image(Imlib_Image * im, feh_file * file) return(1); } #ifdef HAVE_LIBCURL char *feh_http_load_image(char *url) { CURL *curl; CURLcode res; char *sfn; FILE *sfp; int fd = -1; char *ebuff; char *tmpname; char *basename; char *path = NULL; Loading @@ -250,205 +258,6 @@ char *feh_http_load_image(char *url) basename = strrchr(url, '/') + 1; tmpname = feh_unique_filename(path, basename); if (opt.builtin_http) { /* state for HTTP header parser */ #define SAW_NONE 1 #define SAW_ONE_CM 2 #define SAW_ONE_CJ 3 #define SAW_TWO_CM 4 #define IN_BODY 5 #define OUR_BUF_SIZE 1024 #define EOL "\015\012" int sockno = 0; int size; int body = SAW_NONE; struct addrinfo hints; struct addrinfo *result, *rp; char *hostname; char *get_string; char *host_string; char *query_string; char *get_url; static char buf[OUR_BUF_SIZE]; char ua_string[] = "User-Agent: feh image viewer"; char accept_string[] = "Accept: image/*"; FILE *fp; D(("using builtin http collection\n")); fp = fopen(tmpname, "w"); if (!fp) { weprintf("couldn't write to file %s:", tmpname); free(tmpname); return(NULL); } hostname = feh_strip_hostname(url); if (!hostname) { weprintf("couldn't work out hostname from %s:", url); fclose(fp); unlink(tmpname); free(tmpname); return(NULL); } D(("trying hostname %s\n", hostname)); memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICSERV; hints.ai_protocol = 0; if (getaddrinfo(hostname, "80", &hints, &result) != 0) { weprintf("error resolving host %s:", hostname); fclose(fp); unlink(tmpname); free(hostname); free(tmpname); return(NULL); } for (rp = result; rp != NULL; rp = rp->ai_next) { sockno = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sockno == -1) { continue; } if (connect(sockno, rp->ai_addr, rp->ai_addrlen) != -1) { break; } close(sockno); } if (rp == NULL) { weprintf("error connecting socket:"); freeaddrinfo(result); fclose(fp); unlink(tmpname); free(tmpname); free(hostname); return(NULL); } freeaddrinfo(result); get_url = strchr(url, '/') + 2; get_url = strchr(get_url, '/'); get_string = estrjoin(" ", "GET", get_url, "HTTP/1.0", NULL); host_string = estrjoin(" ", "Host:", hostname, NULL); query_string = estrjoin(EOL, get_string, host_string, accept_string, ua_string, "", "", NULL); /* At this point query_string looks something like ** ** GET /dir/foo.jpg?123456 HTTP/1.0^M^J ** Host: www.example.com^M^J ** Accept: image/ *^M^J ** User-Agent: feh image viewer^M^J ** ^M^J ** ** Host: is required by HTTP/1.1 and very important for some sites, ** even with HTTP/1.0 ** ** -- BEG */ if ((send(sockno, query_string, strlen(query_string), 0)) == -1) { free(get_string); free(host_string); free(query_string); free(tmpname); free(hostname); weprintf("error sending over socket:"); return(NULL); } free(get_string); free(host_string); free(query_string); free(hostname); while ((size = read(sockno, &buf, OUR_BUF_SIZE))) { if (body == IN_BODY) { fwrite(buf, 1, size, fp); } else { int i; for (i = 0; i < size; i++) { /* We are looking for ^M^J^M^J, but will accept ** ^J^J from broken servers. Stray ^Ms will be ** ignored. ** ** TODO: ** Checking the headers for a ** Content-Type: image/ * ** header would help detect problems with results. ** Maybe look at the response code too? But there is ** no fundamental reason why a 4xx or 5xx response ** could not return an image, it is just the 3xx ** series we need to worry about. ** ** Also, grabbing the size from the Content-Length ** header and killing the connection after that ** many bytes where read would speed up closing the ** socket. ** -- BEG */ switch (body) { case IN_BODY: fwrite(buf + i, 1, size - i, fp); i = size; break; case SAW_ONE_CM: if (buf[i] == '\012') { body = SAW_ONE_CJ; } else { body = SAW_NONE; } break; case SAW_ONE_CJ: if (buf[i] == '\015') { body = SAW_TWO_CM; } else { if (buf[i] == '\012') { body = IN_BODY; } else { body = SAW_NONE; } } break; case SAW_TWO_CM: if (buf[i] == '\012') { body = IN_BODY; } else { body = SAW_NONE; } break; case SAW_NONE: if (buf[i] == '\015') { body = SAW_ONE_CM; } else { if (buf[i] == '\012') { body = SAW_ONE_CJ; } } break; } /* switch */ } /* for i */ } } /* while read */ close(sockno); fclose(fp); #ifdef HAVE_LIBCURL } else { CURL *curl; CURLcode res; char *sfn; FILE *sfp; int fd = -1; char *ebuff; curl = curl_easy_init(); if (!curl) { weprintf("open url: libcurl initialization failure"); Loading Loading @@ -493,15 +302,19 @@ char *feh_http_load_image(char *url) curl_easy_cleanup(curl); return NULL; } #else } else { weprintf("Please compile feh with curl=1 to enable http support"); #else /* HAVE_LIBCURL */ char *feh_http_load_image(char *url) { weprintf( "Cannot load image %s\n Please recompile with libcurl support", url ); return NULL; } #endif return(tmpname); } #endif /* HAVE_LIBCURL */ char *feh_strip_hostname(char *url) { Loading
src/options.c +1 −7 Original line number Diff line number Diff line Loading @@ -81,8 +81,6 @@ void init_parse_options(int argc, char **argv) opt.start_list_at = NULL; opt.jump_on_resort = 1; opt.builtin_http = 0; opt.xinerama = 0; opt.screen_clip = 1; #ifdef HAVE_LIBXINERAMA Loading Loading @@ -324,7 +322,7 @@ static void feh_getopt_theme(int argc, char **argv) static void feh_parse_option_array(int argc, char **argv) { static char stropts[] = "a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:J:kK:lL:mM:nNo:O:pPqQrR:sS:tT:uUvVwW:xXy:YzZ" "a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:J:kK:lL:mM:nNo:O:pPqrR:sS:tT:uUvVwW:xXy:YzZ" "0:1:2:4:5:8:9:.@:^:~:):|:+:"; /* (*name, has_arg, *flag, val) See: struct option in getopts.h */ Loading Loading @@ -355,7 +353,6 @@ static void feh_parse_option_array(int argc, char **argv) {"preload" , 0, 0, 'p'}, {"reverse" , 0, 0, 'n'}, {"thumbnails" , 0, 0, 't'}, {"builtin" , 0, 0, 'Q'}, {"scale-down" , 0, 0, '.'}, {"no-jump-on-resort", 0, 0, 220}, {"hide-pointer" , 0, 0, 'Y'}, Loading Loading @@ -470,9 +467,6 @@ static void feh_parse_option_array(int argc, char **argv) opt.list = 1; opt.display = 0; break; case 'Q': opt.builtin_http = 1; break; case 'L': opt.customlist = estrdup(optarg); opt.display = 0; Loading
src/options.h +0 −2 Original line number Diff line number Diff line Loading @@ -63,8 +63,6 @@ struct __fehoptions { unsigned char reverse; unsigned char no_menus; unsigned char scale_down; unsigned char builtin_http; unsigned char libcurl_http; unsigned char bgmode; unsigned char xinerama; unsigned char screen_clip; Loading