From: Heng Li Date: Tue, 30 Jun 2009 13:04:30 +0000 (+0000) Subject: * samtools-0.1.4-20 (r365) X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=3b5a80b412333883de8da5b449d2ff097e82afd1;p=samtools.git * samtools-0.1.4-20 (r365) * download the BAM index file if it is not found in the current working directory. --- diff --git a/bam_index.c b/bam_index.c index 1c0b29b..329df32 100644 --- a/bam_index.c +++ b/bam_index.c @@ -3,6 +3,7 @@ #include "khash.h" #include "ksort.h" #include "bam_endian.h" +#include "knetfile.h" /*! @header @@ -321,16 +322,7 @@ static bam_index_t *bam_index_load_core(FILE *fp) return idx; } -bam_index_t *bam_index_load2(const char *fnidx) -{ - bam_index_t *idx; - FILE *fp = fopen(fnidx, "r"); - idx = bam_index_load_core(fp); - fclose(fp); - return idx; -} - -bam_index_t *bam_index_load(const char *_fn) +bam_index_t *bam_index_load_local(const char *_fn) { bam_index_t *idx; FILE *fp; @@ -360,6 +352,51 @@ bam_index_t *bam_index_load(const char *_fn) return idx; } +static void download_from_remote(const char *url) +{ + const int buf_size = 1 * 1024 * 1024; + char *fn; + FILE *fp; + uint8_t *buf; + knetFile *fp_remote; + int l; + if (strstr(url, "ftp://") != url) return; + l = strlen(url); + for (fn = (char*)url + l - 1; fn >= url; --fn) + if (*fn == '/') break; + ++fn; // fn now points to the file name + fp_remote = knet_open(url, "r"); + if (fp_remote == 0) { + fprintf(stderr, "[download_from_remote] fail to open remote file.\n"); + return; + } + if ((fp = fopen(fn, "w")) == 0) { + fprintf(stderr, "[download_from_remote] fail to create file in the working directory.\n"); + knet_close(fp_remote); + return; + } + buf = (uint8_t*)calloc(buf_size, 1); + while ((l = knet_read(fp_remote, buf, buf_size)) != 0) + fwrite(buf, 1, l, fp); + free(buf); + fclose(fp); + knet_close(fp_remote); +} + +bam_index_t *bam_index_load(const char *fn) +{ + bam_index_t *idx; + idx = bam_index_load_local(fn); + if (idx == 0 && strstr(fn, "ftp://") == fn) { + char *fnidx = calloc(strlen(fn) + 5, 1); + strcat(strcpy(fnidx, fn), ".bai"); + fprintf(stderr, "[bam_index_load] attempting to download the remote index file.\n"); + download_from_remote(fnidx); + idx = bam_index_load_local(fn); + } + return idx; +} + int bam_index_build2(const char *fn, const char *_fnidx) { char *fnidx; diff --git a/bamtk.c b/bamtk.c index db42873..61ead10 100644 --- a/bamtk.c +++ b/bamtk.c @@ -3,7 +3,7 @@ #include "bam.h" #ifndef PACKAGE_VERSION -#define PACKAGE_VERSION "0.1.4-19 (r364)" +#define PACKAGE_VERSION "0.1.4-20 (r365)" #endif int bam_taf2baf(int argc, char *argv[]); diff --git a/knetfile.c b/knetfile.c index 45c921f..8dd7e86 100644 --- a/knetfile.c +++ b/knetfile.c @@ -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; @@ -156,6 +156,7 @@ int kftp_connect_file(knetFile *fp) fprintf(stderr, "[kftp_connect_file] %s\n", fp->response); close(fp->fd); fp->fd = -1; + return -1; } fp->is_ready = 1; return 0; @@ -169,7 +170,7 @@ 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); diff --git a/knetfile.h b/knetfile.h index 85f348c..bf45f3d 100644 --- a/knetfile.h +++ b/knetfile.h @@ -29,8 +29,22 @@ extern "C" { #endif knetFile *knet_open(const char *fn, const char *mode); + + /* + This only works with local files. + */ knetFile *knet_dopen(int fd, const char *mode); + + /* + If ->is_ready==0, this routine updates ->fd; otherwise, it simply + reads from ->fd. + */ off_t knet_read(knetFile *fp, void *buf, off_t len); + + /* + This routine only sets ->offset and ->is_ready=0. It does not + communicate with the FTP server. + */ int knet_seek(knetFile *fp, off_t off, int whence); int knet_close(knetFile *fp);