static void fsp_disconnect (gftp_request * request) { fsp_protocol_data * lpd; g_return_if_fail (request != NULL); g_return_if_fail (request->protonum == GFTP_FSP_NUM); lpd = request->protocol_data; g_return_if_fail (lpd != NULL); if(lpd->file) { fsp_fclose(lpd->file); lpd->file=NULL; } fsp_close_session(lpd->fsp); lpd->fsp=NULL; request->datafd = -1; if(lpd->dir) { fsp_closedir(lpd->dir); lpd->dir=NULL; } }
static void fsp_directory(FSP_SESSION *ses, struct uri *uri) { struct string buf; FSP_DIR *dir; unsigned char *data = get_uri_string(uri, URI_DATA); unsigned char dircolor[8] = ""; if (!data) fsp_error(connection_state(S_OUT_OF_MEM)); decode_uri(data); if (!is_in_state(init_directory_listing(&buf, uri), S_OK)) fsp_error(connection_state(S_OUT_OF_MEM)); dir = fsp_opendir(ses, data); if (!dir) fsp_error(connection_state_for_errno(errno)); fprintf(stderr, "text/html"); fclose(stderr); puts(buf.source); if (get_opt_bool("document.browse.links.color_dirs", NULL)) { color_to_string(get_opt_color("document.colors.dirs", NULL), dircolor); } sort_and_display_entries(dir, dircolor); fsp_closedir(dir); puts("</pre><hr/></body></html>"); fsp_close_session(ses); exit(0); }
static void do_fsp(struct connection *conn) { FSP_SESSION *ses; struct stat sb; struct uri *uri = conn->uri; struct auth_entry *auth; unsigned char *host = get_uri_string(uri, URI_HOST); unsigned char *data = get_uri_string(uri, URI_DATA); unsigned short port = (unsigned short)get_uri_port(uri); unsigned char *password = NULL; decode_uri(data); if (uri->passwordlen) { password = get_uri_string(uri, URI_PASSWORD); } else { auth = find_auth(uri); if (auth) password = auth->password; } /* fsp_open_session may not set errno if getaddrinfo fails * https://sourceforge.net/tracker/index.php?func=detail&aid=2036798&group_id=93841&atid=605738 * Try to detect this bug and use an ELinks-specific error * code instead, so that we can display a message anyway. */ errno = 0; ses = fsp_open_session(host, port, password); if (!ses) { if (errno) fsp_error(connection_state_for_errno(errno)); else fsp_error(connection_state(S_FSP_OPEN_SESSION_UNKN)); } /* fsplib 0.8 ABI depends on _FILE_OFFSET_BITS * https://sourceforge.net/tracker/index.php?func=detail&aid=1674729&group_id=93841&atid=605738 * If ELinks and fsplib are using different values of * _FILE_OFFSET_BITS, then they get different definitions of * struct stat, and the st_size stored by fsp_stat is * typically not the same as the st_size read by ELinks. * Fortunately, st_mode seems to have the same offset and size * in both versions of struct stat. * * If all the bytes used by the 32-bit st_size are also used * by the 64-bit st_size, then ELinks may be able to guess * which ones they are, because the current version 2 of FSP * supports only 32-bit file sizes in protocol packets. Begin * by filling struct stat with 0xAA so that it's easier to * detect which bytes fsp_stat has left unchanged. (Only * sb.st_size really needs to be filled, but filling the rest * too helps viewing the data with a debugger.) */ memset(&sb, 0xAA, sizeof(sb)); if (fsp_stat(ses, data, &sb)) fsp_error(connection_state_for_errno(errno)); if (S_ISDIR(sb.st_mode)) { fsp_directory(ses, uri); } else { /* regular file */ char buf[READ_SIZE]; FSP_FILE *file = fsp_fopen(ses, data, "r"); int r; if (!file) { fsp_error(connection_state_for_errno(errno)); } #if SIZEOF_OFF_T >= 8 if (sb.st_size < 0 || sb.st_size > 0xFFFFFFFF) { /* Probably a _FILE_OFFSET_BITS mismatch as * described above. Try to detect which half * of st_size is the real size. This may * depend on the endianness of the processor * and on the padding in struct stat. */ if ((sb.st_size & 0xFFFFFFFF00000000ULL) == 0xAAAAAAAA00000000ULL) sb.st_size = sb.st_size & 0xFFFFFFFF; else if ((sb.st_size & 0xFFFFFFFF) == 0xAAAAAAAA) sb.st_size = (sb.st_size >> 32) & 0xFFFFFFFF; else /* Can't figure it out. */ sb.st_size = 1; } #endif /* Send filesize */ fprintf(stderr, "%" OFF_PRINT_FORMAT "\n", (off_print_T) sb.st_size); fclose(stderr); while ((r = fsp_fread(buf, 1, READ_SIZE, file)) > 0) { int off = 0; while (r) { int w = safe_write(STDOUT_FILENO, buf + off, r); if (w == -1) goto out; off += w; r -= w; } } out: fsp_fclose(file); fsp_close_session(ses); exit(0); }