]> git.donarmstrong.com Git - samtools.git/blobdiff - knetfile.c
* samtools-0.1.4-20 (r365)
[samtools.git] / knetfile.c
index 322885a379642d19b638a9b0164b153cdcf5ed0b..8dd7e86b896c54ffcbb6f48eca0e0991eed9ca1b 100644 (file)
@@ -15,7 +15,7 @@ static int kftp_get_response(knetFile *ftp)
        int n = 0;
        char *p;
        while (read(ftp->ctrl_fd, &c, 1)) { // FIXME: this is *VERY BAD* for unbuffered I/O
-//             fputc(c, stderr);
+               //fputc(c, stderr);
                if (n >= ftp->max_response) {
                        ftp->max_response = ftp->max_response? ftp->max_response<<1 : 256;
                        ftp->response = realloc(ftp->response, ftp->max_response);
@@ -116,7 +116,7 @@ int kftp_reconnect(knetFile *ftp)
 }
 
 // initialize ->type, ->host and ->retr
-knetFile *kftp_prep(const char *fn, const char *mode)
+knetFile *kftp_parse_url(const char *fn, const char *mode)
 {
        knetFile *fp;
        char *p;
@@ -132,25 +132,33 @@ knetFile *kftp_prep(const char *fn, const char *mode)
        strncpy(fp->host, fn + 6, l);
        fp->retr = calloc(strlen(p) + 8, 1);
        sprintf(fp->retr, "RETR %s\r\n", p);
+       fp->seek_offset = -1;
        return fp;
 }
 // place ->fd at offset off
-int kftp_connect_file(knetFile *fp, off_t off)
+int kftp_connect_file(knetFile *fp)
 {
+       int ret;
        if (fp->fd) {
                close(fp->fd);
                if (fp->no_reconnect) kftp_get_response(fp);
        }
        kftp_pasv_prep(fp);
-       if (off) {
+       if (fp->offset) {
                char tmp[32];
-               sprintf(tmp, "REST %lld\r\n", (long long)off);
+               sprintf(tmp, "REST %lld\r\n", (long long)fp->offset);
                kftp_send_cmd(fp, tmp, 1);
        }
        kftp_send_cmd(fp, fp->retr, 0);
        kftp_pasv_connect(fp);
-       kftp_get_response(fp);
-       fp->offset = off;
+       ret = kftp_get_response(fp);
+       if (ret != 150) {
+               fprintf(stderr, "[kftp_connect_file] %s\n", fp->response);
+               close(fp->fd);
+               fp->fd = -1;
+               return -1;
+       }
+       fp->is_ready = 1;
        return 0;
 }
 
@@ -162,13 +170,17 @@ knetFile *knet_open(const char *fn, const char *mode)
                return 0;
        }
        if (strstr(fn, "ftp://") == fn) {
-               fp = kftp_prep(fn, mode);
+               fp = kftp_parse_url(fn, mode);
                if (fp == 0) return 0;
                if (kftp_connect(fp) == -1) {
                        knet_close(fp);
                        return 0;
                }
-               kftp_connect_file(fp, 0);
+               kftp_connect_file(fp);
+               if (fp->fd == -1) {
+                       knet_close(fp);
+                       return 0;
+               }
        } else {
                int fd = open(fn, O_RDONLY);
                if (fd == -1) {
@@ -193,11 +205,17 @@ knetFile *knet_dopen(int fd, const char *mode)
 off_t knet_read(knetFile *fp, void *buf, off_t len)
 {
        off_t l = 0;
+       if (fp->fd < 0) return 0;
        if (fp->type == KNF_TYPE_LOCAL) {
                l = read(fp->fd, buf, len);
                fp->offset += l;
        } else {
                off_t rest = len, curr;
+               if (fp->is_ready == 0) {
+                       if (!fp->no_reconnect) kftp_reconnect(fp);
+                       kftp_connect_file(fp);
+                       fp->is_ready = 1;
+               }
                while (rest) {
                        curr = read(fp->fd, buf + l, rest);
                        if (curr == 0) break; // FIXME: end of file or bad network? I do not know...
@@ -223,8 +241,8 @@ int knet_seek(knetFile *fp, off_t off, int whence)
                        fprintf(stderr, "[knet_seek] only SEEK_SET is supported for FTP. Offset is unchanged.\n");
                        return -1;
                }
-               if (!fp->no_reconnect) kftp_reconnect(fp);
-               kftp_connect_file(fp, off);
+               fp->offset = off;
+               fp->is_ready = 0;
                return 0;
        }
        return -1;