ssize_t knet_read(knetFile *fp, void *buf, size_t len) { off_t l = 0; if (fp->fd == -1) return 0; if (fp->type == KNF_TYPE_FTP) { if (fp->is_ready == 0) { if (!fp->no_reconnect) kftp_reconnect(fp); kftp_connect_file(fp); } } else if (fp->type == KNF_TYPE_HTTP) { if (fp->is_ready == 0) khttp_connect_file(fp); } if (fp->type == KNF_TYPE_LOCAL) { // on Windows, the following block is necessary; not on UNIX size_t rest = len; ssize_t curr; while (rest) { do { curr = read(fp->fd, (void*)((char*)buf + l), rest); } while (curr < 0 && EINTR == errno); if (curr < 0) return -1; if (curr == 0) break; l += curr; rest -= curr; } } else l = my_netread(fp->fd, buf, len); fp->offset += l; return l; }
off_t knet_read(knetFile *fp, void *buf, off_t len) { off_t l = 0; if (fp->fd == -1) return 0; if (fp->type == KNF_TYPE_FTP) { if (fp->is_ready == 0) { if (!fp->no_reconnect) kftp_reconnect(fp); kftp_connect_file(fp); } } else if (fp->type == KNF_TYPE_HTTP) { if (fp->is_ready == 0) khttp_connect_file(fp); } if (fp->type == KNF_TYPE_LOCAL) { // on Windows, the following block is necessary; not on UNIX off_t rest = len, curr; while (rest) { curr = read(fp->fd, buf + l, rest); if (curr == 0) break; l += curr; rest -= curr; } } else l = my_netread(fp->fd, buf, len); fp->offset += l; return l; }
int khttp_connect_file(knetFile *fp) { int ret, l = 0; char *buf, *p; if (fp->fd != -1) netclose(fp->fd); fp->fd = socket_connect(fp->host, fp->port); buf = (char*)calloc(0x10000, 1); // FIXME: I am lazy... But in principle, 64KB should be large enough. l += sprintf(buf + l, "GET %s HTTP/1.0\r\nHost: %s\r\n", fp->path, fp->http_host); l += sprintf(buf + l, "Range: bytes=%lld-\r\n", (long long)fp->offset); l += sprintf(buf + l, "\r\n"); if ( netwrite(fp->fd, buf, l) != l ) { free(buf); return -1; } l = 0; while (netread(fp->fd, buf + l, 1)) { // read HTTP header; FIXME: bad efficiency if (buf[l] == '\n' && l >= 3) if (strncmp(buf + l - 3, "\r\n\r\n", 4) == 0) break; ++l; } buf[l] = 0; if (l < 14) { // prematured header free(buf); netclose(fp->fd); fp->fd = -1; return -1; } ret = strtol(buf + 8, &p, 0); // HTTP return code if (ret == 200 && fp->offset>0) { // 200 (complete result); then skip beginning of the file off_t rest = fp->offset; while (rest) { off_t l = rest < 0x10000? rest : 0x10000; rest -= my_netread(fp->fd, buf, l); } } else if (ret != 206 && ret != 200) { // failed to open file free(buf); netclose(fp->fd); switch (ret) { case 401: errno = EPERM; break; case 403: errno = EACCES; break; case 404: errno = ENOENT; break; case 407: errno = EPERM; break; case 408: errno = ETIMEDOUT; break; case 410: errno = ENOENT; break; case 503: errno = EAGAIN; break; case 504: errno = ETIMEDOUT; break; default: errno = (ret >= 400 && ret < 500)? EINVAL : EIO; break; } fp->fd = -1; return -1; } free(buf); fp->is_ready = 1; return 0; }
int khttp_connect_file(knetFile *fp) { int ret, l = 0; char *buf, *p; ssize_t byteswritten; if (fp->fd != -1) netclose(fp->fd); fp->fd = socket_connect(fp->host, fp->port); buf = calloc(0x10000, 1); /* FIXME: I am lazy... But in principle, 64KB should be large enough. */ l += sprintf(buf + l, "GET %s HTTP/1.0\r\nHost: %s\r\n", fp->path, fp->http_host); l += sprintf(buf + l, "Range: bytes=%" PRId64 "-\r\n", fp->offset); l += sprintf(buf + l, "\r\n"); byteswritten = netwrite(fp->fd, buf, l); /* @ubw fixed unused result warning */ if( 0 >= byteswritten ) /* do sth with the result */ { PRINT_ERROR( "[khttp_connect_file] no (%d) bytes written in GET request!\n", byteswritten); /* return -1; */ /* cppcheck : [dev/src/tabix/knetfile.c:440]: (error) Memory leak: buf ||| free(buf) the buf=calloc() from line 432 ! */ free( buf ); return -1; } l = 0; while (netread(fp->fd, buf + l, 1)) { /* read HTTP header; FIXME: bad efficiency */ if (buf[l] == '\n' && l >= 3) if (strncmp(buf + l - 3, "\r\n\r\n", 4) == 0) break; ++l; } buf[l] = 0; if (l < 14) { /* prematured header */ netclose(fp->fd); fp->fd = -1; return -1; } ret = strtol(buf + 8, &p, 0); /* HTTP return code */ if (ret == 200 && fp->offset>0) { /* 200 (complete result); then skip beginning of the file */ off_t rest = fp->offset; while (rest) { off_t l = rest < 0x10000? rest : 0x10000; rest -= my_netread(fp->fd, buf, l); } } else if (ret != 206 && ret != 200) { free(buf); PRINT_ERROR( "[khttp_connect_file] fail to open file (HTTP code: %d).\n", ret); netclose(fp->fd); fp->fd = -1; return -1; } free(buf); fp->is_ready = 1; return 0; }
int khttp_connect_file(knetFile *fp) { int ret, l = 0; char *buf, *p; if (fp->fd != -1) netclose(fp->fd); fp->fd = socket_connect(fp->host, fp->port); buf = (char*)calloc(0x10000, 1); // FIXME: I am lazy... But in principle, 64KB should be large enough. l += sprintf(buf + l, "GET %s HTTP/1.0\r\nHost: %s\r\n", fp->path, fp->http_host); l += sprintf(buf + l, "Range: bytes=%lld-\r\n", (long long)fp->offset); l += sprintf(buf + l, "\r\n"); if(netwrite(fp->fd, buf, l) != l) { } l = 0; while (netread(fp->fd, buf + l, 1)) { // read HTTP header; FIXME: bad efficiency if (buf[l] == '\n' && l >= 3) if (strncmp(buf + l - 3, "\r\n\r\n", 4) == 0) break; ++l; } buf[l] = 0; if (l < 14) { // prematured header netclose(fp->fd); fp->fd = -1; return -1; } ret = strtol(buf + 8, &p, 0); // HTTP return code if (ret == 200 && fp->offset>0) { // 200 (complete result); then skip beginning of the file off_t rest = fp->offset; while (rest) { off_t l = rest < 0x10000? rest : 0x10000; rest -= my_netread(fp->fd, buf, l); } } else if (ret != 206 && ret != 200) { free(buf); if(!knetsilent) { fprintf(stderr, "[khttp_connect_file] fail to open file (HTTP code: %d).\n", ret); } netclose(fp->fd); fp->fd = -1; return -1; } free(buf); fp->is_ready = 1; return 0; }