int btFiles::BuildFromFS(const char *pathname) { struct stat sb; BTFILE *pbf = (BTFILE*) 0; if( stat(pathname, &sb) < 0 ){ fprintf(stderr,"error, stat file %s failed, %s\n",pathname,strerror(errno)); return -1; } if( S_IFREG & sb.st_mode ){ pbf = _new_bfnode(); #ifndef WINDOWS if( !pbf ) return -1; #endif pbf->bf_length = m_total_files_length = sb.st_size; pbf->bf_filename = new char[strlen(pathname) + 1]; #ifndef WINDOWS if( !pbf->bf_filename ) return -1; #endif strcpy(pbf->bf_filename, pathname); m_btfhead = pbf; }else if( S_IFDIR & sb.st_mode ){ char wd[MAXPATHLEN]; #if HAVE_GETCWD if( !getcwd(wd,MAXPATHLEN) ) return -1; #else if( !getwd(wd) ) return -1; #endif m_directory = new char[strlen(pathname) + 1]; #ifndef WINDOWS if( !m_directory ) return -1; #endif strcpy(m_directory, pathname); if(chdir(m_directory) < 0){ fprintf(stderr,"error, change work directory to %s failed, %s",m_directory, strerror(errno)); return -1; } if(_btf_recurses_directory((const char*)0, (BTFILE*) 0) < 0) return -1; if( chdir(wd) < 0) return -1; }else{ fprintf(stderr,"error, %s is not a directory or regular file.\n",pathname); return -1; } return 0; }
int btFiles::BuildFromFS(const char *pathname) { struct stat sb; BTFILE *pbf = (BTFILE*) 0; BTFILE *lastnode = (BTFILE*) 0; if( stat(pathname, &sb) < 0 ){ CONSOLE.Warning(1, "error, stat file \"%s\" failed: %s", pathname, strerror(errno)); return -1; } if( S_IFREG & sb.st_mode ){ pbf = _new_bfnode(); #ifndef WINDOWS if( !pbf ) return -1; #endif pbf->bf_length = m_total_files_length = sb.st_size; pbf->bf_filename = new char[strlen(pathname) + 1]; #ifndef WINDOWS if( !pbf->bf_filename ) return -1; #endif strcpy(pbf->bf_filename, pathname); m_btfhead = pbf; }else if( S_IFDIR & sb.st_mode ){ char wd[MAXPATHLEN]; if( !getcwd(wd,MAXPATHLEN) ) return -1; m_directory = new char[strlen(pathname) + 1]; #ifndef WINDOWS if( !m_directory ) return -1; #endif strcpy(m_directory, pathname); if(chdir(m_directory) < 0){ CONSOLE.Warning(1, "error, change work directory to \"%s\" failed: %s", m_directory, strerror(errno)); return -1; } if(_btf_recurses_directory((const char*)0, &lastnode) < 0) return -1; if( chdir(wd) < 0) return -1; }else{ CONSOLE.Warning(1, "error, \"%s\" is not a directory or regular file.", pathname); return -1; } return 0; }
int btFiles::BuildFromMI(const char *metabuf, const size_t metabuf_len, const char *saveas) { char path[MAXPATHLEN]; const char *s, *p; size_t r,q,n; int64_t t; int f_warned = 0; if( !decode_query(metabuf, metabuf_len, "info|name", &s, &q, (int64_t*)0, QUERY_STR) || MAXPATHLEN <= q ) return -1; memcpy(path, s, q); path[q] = '\0'; r = decode_query(metabuf, metabuf_len, "info|files", (const char**)0, &q, (int64_t*)0, QUERY_POS); if( r ){ BTFILE *pbf_last = (BTFILE*) 0; BTFILE *pbf = (BTFILE*) 0; size_t dl; if( decode_query(metabuf,metabuf_len,"info|length", (const char**) 0,(size_t*) 0,(int64_t*) 0,QUERY_LONG) ) return -1; if( saveas ){ m_directory = new char[strlen(saveas) + 1]; #ifndef WINDOWS if(!m_directory) return -1; #endif strcpy(m_directory,saveas); }else{ int f_conv; char *tmpfn = new char[strlen(path)*2+5]; #ifndef WINDOWS if( !tmpfn ) return -1; #endif if( f_conv = ConvertFilename(tmpfn, path, strlen(path)*2+5) ){ if( arg_flg_convert_filenames ){ m_directory = new char[strlen(tmpfn) + 1]; #ifndef WINDOWS if( !m_directory ){ delete []tmpfn; return -1; } #endif strcpy(m_directory,tmpfn); }else{ CONSOLE.Warning(3, "Dir name contains non-printable characters; use -T to convert."); f_warned = 1; } } delete []tmpfn; if( !f_conv || !arg_flg_convert_filenames ){ m_directory = new char[strlen(path) + 1]; #ifndef WINDOWS if( !m_directory ) return -1; #endif strcpy(m_directory,path); } } /* now r saved the pos of files list. q saved list length */ p = metabuf + r + 1; q--; for(; q && 'e' != *p; p += dl, q -= dl){ if(!(dl = decode_dict(p, q, (const char*) 0)) ) return -1; if( !decode_query(p, dl, "length", (const char**) 0, (size_t*) 0,&t,QUERY_LONG) ) return -1; pbf = _new_bfnode(); #ifndef WINDOWS if( !pbf ) return -1; #endif pbf->bf_length = t; m_total_files_length += t; r = decode_query(p, dl, "path", (const char **)0, &n, (int64_t*)0, QUERY_POS); if( !r ) return -1; if(!decode_list2path(p + r, n, path)) return -1; int f_conv; char *tmpfn = new char[strlen(path)*2+5]; #ifndef WINDOWS if( !tmpfn ) return -1; #endif if( f_conv = ConvertFilename(tmpfn, path, strlen(path)*2+5) ){ if( arg_flg_convert_filenames ){ pbf->bf_filename = new char[strlen(tmpfn) + 1]; #ifndef WINDOWS if( !pbf->bf_filename ){ delete []tmpfn; return -1; } #endif strcpy(pbf->bf_filename, tmpfn); }else if(!f_warned){ CONSOLE.Warning(3, "Filename contains non-printable characters; use -T to convert."); f_warned = 1; } } delete []tmpfn; if( !f_conv || !arg_flg_convert_filenames ){ pbf->bf_filename = new char[strlen(path) + 1]; #ifndef WINDOWS if( !pbf->bf_filename ) return -1; #endif strcpy(pbf->bf_filename, path); } if(pbf_last) pbf_last->bf_next = pbf; else m_btfhead = pbf; pbf_last = pbf; } }else{ if( !decode_query(metabuf,metabuf_len,"info|length", (const char**) 0,(size_t*) 0,&t,QUERY_LONG) ) return -1; m_btfhead = _new_bfnode(); #ifndef WINDOWS if( !m_btfhead) return -1; #endif m_btfhead->bf_length = m_total_files_length = t; if( saveas ){ m_btfhead->bf_filename = new char[strlen(saveas) + 1]; #ifndef WINDOWS if(!m_btfhead->bf_filename ) return -1; #endif strcpy(m_btfhead->bf_filename, saveas); }else if( arg_flg_convert_filenames ){ char *tmpfn = new char[strlen(path)*2+5]; #ifndef WINDOWS if( !tmpfn ) return -1; #endif ConvertFilename(tmpfn, path, strlen(path)*2+5); m_btfhead->bf_filename = new char[strlen(tmpfn) + 1]; #ifndef WINDOWS if( !m_btfhead->bf_filename ){ delete []tmpfn; return -1; } #endif strcpy(m_btfhead->bf_filename, tmpfn); delete []tmpfn; }else{ m_btfhead->bf_filename = new char[strlen(path) + 1]; #ifndef WINDOWS if(!m_btfhead->bf_filename ) return -1; #endif strcpy(m_btfhead->bf_filename, path); } } return 0; }
int btFiles::_btf_recurses_directory(const char *cur_path, BTFILE* *plastnode) { char full_cur[MAXPATHLEN]; char fn[MAXPATHLEN]; struct stat sb; struct dirent *dirp; DIR *dp; BTFILE *pbf; if( !getcwd(full_cur,MAXPATHLEN) ) return -1; if( cur_path ){ strcpy(fn, full_cur); if( MAXPATHLEN <= snprintf(full_cur, MAXPATHLEN, "%s%c%s", fn, PATH_SP, cur_path) ){ errno = ENAMETOOLONG; return -1; } } if( (DIR*) 0 == (dp = opendir(full_cur)) ){ CONSOLE.Warning(1, "error, open directory \"%s\" failed: %s", cur_path, strerror(errno)); return -1; } while( (struct dirent*) 0 != (dirp = readdir(dp)) ){ if( 0 == strcmp(dirp->d_name, ".") || 0 == strcmp(dirp->d_name, "..") ) continue; if( cur_path ){ if(MAXPATHLEN < snprintf(fn, MAXPATHLEN, "%s%c%s", cur_path, PATH_SP, dirp->d_name)){ CONSOLE.Warning(1, "error, pathname too long"); errno = ENAMETOOLONG; return -1; } }else{ strcpy(fn, dirp->d_name); } if( stat(fn, &sb) < 0 ){ CONSOLE.Warning(1, "error, stat \"%s\" failed: %s",fn,strerror(errno)); return -1; } if( S_IFREG & sb.st_mode ){ pbf = _new_bfnode(); #ifndef WINDOWS if( !pbf ){ errno = ENOMEM; return -1; } #endif pbf->bf_filename = new char[strlen(fn) + 1]; #ifndef WINDOWS if( !pbf->bf_filename ){ closedir(dp); errno = ENOMEM; return -1; } #endif strcpy(pbf->bf_filename, fn); pbf->bf_length = sb.st_size; m_total_files_length += sb.st_size; if( *plastnode ) (*plastnode)->bf_next = pbf; else m_btfhead = pbf; *plastnode = pbf; }else if( S_IFDIR & sb.st_mode ){ if(_btf_recurses_directory(fn, plastnode) < 0){closedir(dp); return -1;} }else{ CONSOLE.Warning(1, "error, \"%s\" is not a directory or regular file.", fn); closedir(dp); return -1; } } // end while closedir(dp); return 0; }
int btFiles::BuildFromMI(const char *metabuf, const size_t metabuf_len, const char *saveas) { char path[MAXPATHLEN]; const char *s, *p; size_t r,q,n; if( !decode_query(metabuf, metabuf_len, "info|name",&s,&q,QUERY_STR) || MAXPATHLEN <= q) return -1; memcpy(path, s, q); path[q] = '\0'; r = decode_query(metabuf,metabuf_len,"info|files",(const char**) 0, &q,QUERY_POS); if( r ){ BTFILE *pbf_last = (BTFILE*) 0; BTFILE *pbf = (BTFILE*) 0; size_t dl; if( decode_query(metabuf,metabuf_len,"info|length", (const char**) 0,(size_t*) 0,QUERY_INT) ) return -1; if( saveas ){ m_directory = new char[strlen(saveas) + 1]; #ifndef WINDOWS if(!m_directory) return -1; #endif strcpy(m_directory,saveas); }else{ m_directory = new char[strlen(path) + 1]; #ifndef WINDOWS if( !m_directory) return -1; #endif strcpy(m_directory,path); } /* now r saved the pos of files list. q saved list length */ p = metabuf + r + 1; q--; for(; q && 'e' != *p; p += dl, q -= dl){ if(!(dl = decode_dict(p, q, (const char*) 0)) ) return -1; if( !decode_query(p, dl, "length", (const char**) 0, &r,QUERY_INT) ) return -1; pbf = _new_bfnode(); #ifndef WINDOWS if( !pbf ) return -1; #endif pbf->bf_length = r; m_total_files_length += r; r = decode_query(p, dl, "path", (const char **) 0, &n,QUERY_POS); if( !r ) return -1; if(!decode_list2path(p + r, n, path)) return -1; pbf->bf_filename = new char[strlen(path) + 1]; #ifndef WINDOWS if( !pbf->bf_filename ) return -1; #endif strcpy(pbf->bf_filename, path); if(pbf_last) pbf_last->bf_next = pbf; else m_btfhead = pbf; pbf_last = pbf; } }else{ if( !decode_query(metabuf,metabuf_len,"info|length", (const char**) 0,(size_t*) &q,QUERY_INT) ) return -1; m_btfhead = _new_bfnode(); #ifndef WINDOWS if( !m_btfhead) return -1; #endif m_btfhead->bf_length = m_total_files_length = q; if( saveas ){ m_btfhead->bf_filename = new char[strlen(saveas) + 1]; #ifndef WINDOWS if(!m_btfhead->bf_filename ) return -1; #endif strcpy(m_btfhead->bf_filename, saveas); }else{ m_btfhead->bf_filename = new char[strlen(path) + 1]; #ifndef WINDOWS if(!m_btfhead->bf_filename ) return -1; #endif strcpy(m_btfhead->bf_filename, path); } } return 0; }
int btFiles::_btf_recurses_directory(const char *cur_path, BTFILE* lastnode) { char full_cur[MAXPATHLEN]; char fn[MAXPATHLEN]; struct stat sb; struct dirent *dirp; DIR *dp; BTFILE *pbf; #if HAVE_GETCWD if( !getcwd(full_cur,MAXPATHLEN) ) return -1; #else if( !getwd(full_cur) ) return -1; #endif if( cur_path ){ strcpy(fn, full_cur); if( MAXPATHLEN <= snprintf(full_cur, MAXPATHLEN, "%s%c%s", fn, PATH_SP, cur_path)) return -1; } if( (DIR*) 0 == (dp = opendir(full_cur))){ fprintf(stderr,"error, open directory %s failed, %s\n",cur_path,strerror(errno)); return -1; } while( (struct dirent*) 0 != (dirp = readdir(dp)) ){ if( 0 == strcmp(dirp->d_name, ".") || 0 == strcmp(dirp->d_name, "..") ) continue; if( cur_path ){ if(MAXPATHLEN < snprintf(fn, MAXPATHLEN, "%s%c%s", cur_path, PATH_SP, dirp->d_name)){ fprintf(stderr,"error, pathname too long\n"); return -1; } }else{ strcpy(fn, dirp->d_name); } if( stat(fn, &sb) < 0 ){ fprintf(stderr,"error, stat %s failed, %s\n",fn,strerror(errno)); return -1; } if( S_IFREG & sb.st_mode ){ pbf = _new_bfnode(); #ifndef WINDOWS if( !pbf ) return -1; #endif pbf->bf_filename = new char[strlen(fn) + 1]; #ifndef WINDOWS if( !pbf->bf_filename ){ closedir(dp); return -1;} #endif strcpy(pbf->bf_filename, fn); pbf->bf_length = sb.st_size; m_total_files_length += sb.st_size; if( lastnode ) lastnode->bf_next = pbf; else m_btfhead = pbf; lastnode = pbf; }else if( S_IFDIR & sb.st_mode ){ if(_btf_recurses_directory(fn, lastnode) < 0){closedir(dp); return -1;} }else{ fprintf(stderr,"error, %s is not a directory or regular file.\n",fn); closedir(dp); return -1; } } // end while closedir(dp); return 0; }