void SceneXMLParser::loadFluidVolumes(rapidxml::xml_node<>* node, Fluid& fluid) { assert(node != NULL); int volumenum = 0; for (rapidxml::xml_node<>* nd = node->first_node("fluidvolume"); nd; nd = nd->next_sibling("fluidvolume")) { scalar xmin, xmax, ymin, ymax, zmin, zmax; scalar r = 0.317, g = 0.639, b = 1.0, a = 0.5; int numparticles = 100; fluid_volume_mode_t mode; bool random; scalar spacing; bool particle_selected = false; bool spacing_selected = false; if (nd->first_attribute("xmin")) { std::string attribute(nd->first_attribute("xmin")->value()); if( !stringutils::extractFromString(attribute,xmin) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of xmin attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing xmin attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("xmax")) { std::string attribute(nd->first_attribute("xmax")->value()); if( !stringutils::extractFromString(attribute,xmax) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of xmax attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing xmax attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("ymin")) { std::string attribute(nd->first_attribute("ymin")->value()); if( !stringutils::extractFromString(attribute,ymin) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of ymin attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing ymin attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("ymax")) { std::string attribute(nd->first_attribute("ymax")->value()); if( !stringutils::extractFromString(attribute,ymax) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of ymax attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing ymax attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("zmin")) { std::string attribute(nd->first_attribute("zmin")->value()); if( !stringutils::extractFromString(attribute,zmin) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of zmin attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing zmin attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("zmax")) { std::string attribute(nd->first_attribute("zmax")->value()); if( !stringutils::extractFromString(attribute,zmax) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of zmax attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing zmax attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("numparticles")) { std::string attribute(nd->first_attribute("numparticles")->value()); if( !stringutils::extractFromString(attribute,numparticles) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of numparticles attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } particle_selected = true; } if (nd->first_attribute("spacing")) { std::string attribute(nd->first_attribute("spacing")->value()); if( !stringutils::extractFromString(attribute,spacing) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of spacing attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } spacing_selected = true; } if (!particle_selected && !spacing_selected) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing either spacing or numparticles attribute for fluid volume. Values must be scalar. Exiting." << std::endl; exit(1); } if (nd->first_attribute("mode")) { std::string mode_string(nd->first_attribute("mode")->value()); if( mode_string != "box" && mode_string != "sphere" ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of mode attribute for fluid volume. Value must be either box or sphere. Exiting." << std::endl; exit(1); } if (mode_string == "box") { mode = kFLUID_VOLUME_MODE_BOX; } else if (mode_string == "sphere") { mode = kFLUID_VOLUME_MODE_SPHERE; } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing mode attribute for fluid volume. Value must be either box or sphere. Exiting." << std::endl; exit(1); } if (nd->first_attribute("random")) { std::string attribute(nd->first_attribute("random")->value()); if( !stringutils::extractBoolFromString(attribute,random) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of random attribute for fluid volume. Value must be boolean. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Missing random attribute for fluid volume. Value must be boolean. Exiting." << std::endl; exit(1); } if (nd->first_attribute("r")) { std::string attribute(nd->first_attribute("r")->value()); if( !stringutils::extractFromString(attribute,r) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of r attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (r < 0 || r > 1) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of r attribute for fluid volume. Value must be between 0 and 1. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startpink << "Warning in XMLSceneParser:" << outputmod::endpink << "Missing r attribute for fluid volume. Using default values." << std::endl; } if (nd->first_attribute("g")) { std::string attribute(nd->first_attribute("g")->value()); if( !stringutils::extractFromString(attribute,g) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of g attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (g < 0 || g > 1) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of g attribute for fluid volume. Value must be between 0 and 1. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startpink << "Warning in XMLSceneParser:" << outputmod::endpink << "Missing g attribute for fluid volume. Using default values." << std::endl; } if (nd->first_attribute("b")) { std::string attribute(nd->first_attribute("b")->value()); if( !stringutils::extractFromString(attribute,b) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of b attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (b < 0 || b > 1) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of b attribute for fluid volume. Value must be between 0 and 1. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startpink << "Warning in XMLSceneParser:" << outputmod::endpink << "Missing b attribute for fluid volume. Using default values." << std::endl; } if (nd->first_attribute("a")) { std::string attribute(nd->first_attribute("a")->value()); if( !stringutils::extractFromString(attribute,a) ) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of a attribute for fluid volume. Value must be scalar. Exiting." << std::endl; exit(1); } if (a < 0 || a > 1) { std::cerr << outputmod::startred << "ERROR IN XMLSCENEPARSER:" << outputmod::endred << "Failed to parse value of a attribute for fluid volume. Value must be between 0 and 1. Exiting." << std::endl; exit(1); } } else { std::cerr << outputmod::startpink << "Warning in XMLSceneParser:" << outputmod::endpink << "Missing a attribute for fluid volume. Using default values." << std::endl; } FluidVolume volume(xmin, xmax, ymin, ymax, zmin, zmax, numparticles, mode, random, r, g, b, a); if (spacing_selected) { volume.setSpacing(spacing); } fluid.insertFluidVolume(volume); volumenum++; } if (volumenum == 0) { std::cerr << outputmod::startpink << "Warning in XMLSceneParser:" << outputmod::endpink << "No fluid volumes in fluid." << std::endl; } }
static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, file_data_t*dir_list, const unsigned long int inode, const unsigned int depth) { /* Return value * -1: quit * 1: back * other: new inode * */ int quit=0; WINDOW *window=(WINDOW*)dir_data->display; do { int offset=0; int pos_num=0; file_data_t *pos=dir_list; int old_LINES=LINES; unsigned int status=FILE_STATUS_MARKED; aff_copy(window); wmove(window,3,0); aff_part(window, AFF_PART_ORDER|AFF_PART_STATUS, disk, partition); wmove(window,4,0); wprintw(window,"Directory %s\n",dir_data->current_directory); do { int i; int car; const file_data_t *current_file; for(i=0,current_file=dir_list;(current_file!=NULL) && (i<offset);current_file=current_file->next,i++); for(i=offset;(current_file!=NULL) &&((i-offset)<INTER_DIR);i++,current_file=current_file->next) { char str[11]; char datestr[80]; wmove(window, 6+i-offset, 0); wclrtoeol(window); /* before addstr for BSD compatibility */ if(current_file==pos) { wattrset(window, A_REVERSE); waddstr(window, ">"); } else waddstr(window, " "); if((current_file->status&FILE_STATUS_DELETED)!=0 && has_colors()) wbkgdset(window,' ' | COLOR_PAIR(1)); else if((current_file->status&FILE_STATUS_MARKED)!=0 && has_colors()) wbkgdset(window,' ' | COLOR_PAIR(2)); if(current_file->td_mtime!=0) { struct tm *tm_p; tm_p = localtime(¤t_file->td_mtime); snprintf(datestr, sizeof(datestr),"%2d-%s-%4d %02d:%02d", tm_p->tm_mday, monstr[tm_p->tm_mon], 1900 + tm_p->tm_year, tm_p->tm_hour, tm_p->tm_min); /* May have to use %d instead of %e */ } else { strncpy(datestr, " ",sizeof(datestr)); } mode_string(current_file->st_mode, str); wprintw(window, "%s %5u %5u ", str, (unsigned int)current_file->st_uid, (unsigned int)current_file->st_gid); wprintw(window, "%9llu", (long long unsigned int)current_file->st_size); /* screen may overlap due to long filename */ wprintw(window, " %s %s", datestr, current_file->name); if(((current_file->status&FILE_STATUS_DELETED)!=0 || (current_file->status&FILE_STATUS_MARKED)!=0) && has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); if(current_file==pos) wattroff(window, A_REVERSE); } wmove(window, 6-1, 51); wclrtoeol(window); if(offset>0) wprintw(window, "Previous"); /* Clear the last line, useful if overlapping */ wmove(window,6+i-offset,0); wclrtoeol(window); wmove(window, 6+INTER_DIR, 51); wclrtoeol(window); if(current_file!=NULL) wprintw(window, "Next"); if(dir_list==NULL) { wmove(window,6,0); wprintw(window,"No file found, filesystem may be damaged."); } /* Redraw the bottom of the screen everytime because very long filenames may have corrupt it*/ mvwaddstr(window,LINES-3,0,"Use "); if(depth>0) { if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window, "Left"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); waddstr(window," arrow to go back, "); } if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window,"Right"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); waddstr(window," to change directory"); if((dir_data->capabilities&CAPA_LIST_DELETED)!=0) { waddstr(window,", "); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window,"h"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); if((dir_data->param&FLAG_LIST_DELETED)==0) waddstr(window," to unhide deleted files"); else waddstr(window," to hide deleted files"); } wmove(window,LINES-2,4); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window,"q"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); waddstr(window," to quit"); if(dir_data->copy_file!=NULL) { waddstr(window,", "); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window,":"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); waddstr(window," to select the current file, "); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window,"a"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); if((status&FILE_STATUS_MARKED)==FILE_STATUS_MARKED) waddstr(window," to select all files "); else waddstr(window," to deselect all files"); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); mvwaddstr(window,LINES-1,4,"C"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); waddstr(window," to copy the selected files, "); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window,"c"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); waddstr(window," to copy the current file"); } wrefresh(window); /* Using gnome terminal under FC3, TERM=xterm, the screen is not always correct */ wredrawln(window,0,getmaxy(window)); /* redrawwin def is boggus in pdcur24 */ car=wgetch(window); wmove(window,5,0); wclrtoeol(window); switch(car) { case key_ESC: case 'q': case 'M': quit=1; break; case '-': case KEY_LEFT: case '4': if(depth>0) return 1; break; case 'h': if((dir_data->capabilities&CAPA_LIST_DELETED)!=0) dir_data->param^=FLAG_LIST_DELETED; return inode; } if(dir_list!=NULL) { switch(car) { case KEY_UP: case '8': if(pos->prev!=NULL) { pos=pos->prev; pos_num--; } break; case KEY_DOWN: case '2': if(pos->next!=NULL) { pos=pos->next; pos_num++; } break; case ':': if(!(pos->name[0]=='.' && pos->name[1]=='\0') && !(pos->name[0]=='.' && pos->name[1]=='.' && pos->name[2]=='\0')) pos->status^=FILE_STATUS_MARKED; if(pos->next!=NULL) { pos=pos->next; pos_num++; } break; case 'a': { file_data_t *tmp; for(tmp=dir_list; tmp!=NULL; tmp=tmp->next) { if((tmp->name[0]=='.' && tmp->name[1]=='\0') || (tmp->name[0]=='.' && tmp->name[1]=='.' && tmp->name[2]=='\0')) { tmp->status&=~FILE_STATUS_MARKED; } else { if((tmp->status & FILE_STATUS_MARKED)!=status) tmp->status^=FILE_STATUS_MARKED; } } status^=FILE_STATUS_MARKED; } break; case 'p': case 'P': case '+': case ' ': case KEY_RIGHT: case '\r': case '\n': case '6': case KEY_ENTER: #ifdef PADENTER case PADENTER: #endif if((pos!=NULL) && (LINUX_S_ISDIR(pos->st_mode)!=0)) { unsigned long int new_inode=pos->st_ino; if((new_inode!=inode) &&(strcmp(pos->name,".")!=0)) { if(strcmp(pos->name,"..")==0) return 1; if(strlen(dir_data->current_directory)+1+strlen(pos->name)+1<=sizeof(dir_data->current_directory)) { if(strcmp(dir_data->current_directory,"/")) strcat(dir_data->current_directory,"/"); strcat(dir_data->current_directory,pos->name); return (long int)new_inode; } } } break; case KEY_PPAGE: for(i=0;(i<INTER_DIR-1)&&(pos->prev!=NULL);i++) { pos=pos->prev; pos_num--; } break; case KEY_NPAGE: for(i=0;(i<INTER_DIR-1)&&(pos->next!=NULL);i++) { pos=pos->next; pos_num++; } break; case 'c': if(dir_data->copy_file!=NULL) { const unsigned int current_directory_namelength=strlen(dir_data->current_directory); if(strcmp(pos->name,"..")!=0 && current_directory_namelength+1+strlen(pos->name)<sizeof(dir_data->current_directory)-1) { if(strcmp(dir_data->current_directory,"/")) strcat(dir_data->current_directory,"/"); if(strcmp(pos->name,".")!=0) strcat(dir_data->current_directory,pos->name); if(dir_data->local_dir==NULL) { if(LINUX_S_ISDIR(pos->st_mode)!=0) dir_data->local_dir=ask_location("Please select a destination where %s and any files below will be copied.", dir_data->current_directory, NULL); else dir_data->local_dir=ask_location("Please select a destination where %s will be copied.", dir_data->current_directory, NULL); } if(dir_data->local_dir!=NULL) { int res=-1; wmove(window,5,0); wclrtoeol(window); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1)); wprintw(window,"Copying, please wait..."); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); wrefresh(window); if(LINUX_S_ISDIR(pos->st_mode)!=0) { res=copy_dir(disk, partition, dir_data, pos); } else if(LINUX_S_ISREG(pos->st_mode)!=0) { res=dir_data->copy_file(disk, partition, dir_data, pos); } wmove(window,5,0); wclrtoeol(window); if(res < -1) { if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1)); wprintw(window,"Copy failed!"); } else { if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(2)); if(res < 0) wprintw(window,"Copy done! (Failed to copy some files)"); else wprintw(window,"Copy done!"); } if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); } dir_data->current_directory[current_directory_namelength]='\0'; } } break; case 'C': if(dir_data->copy_file!=NULL) { if(dir_data->local_dir==NULL) { dir_data->local_dir=ask_location("Please select a destination where the marked files will be copied.", NULL, NULL); } if(dir_data->local_dir!=NULL) { file_data_t *tmp; int copy_bad=0; int copy_ok=0; const unsigned int current_directory_namelength=strlen(dir_data->current_directory); wmove(window,5,0); wclrtoeol(window); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1)); wprintw(window,"Copying, please wait..."); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); wrefresh(window); for(tmp=dir_list; tmp!=NULL; tmp=tmp->next) { if((tmp->status&FILE_STATUS_MARKED)!=0 && current_directory_namelength + 1 + strlen(tmp->name) < sizeof(dir_data->current_directory)-1) { if(strcmp(dir_data->current_directory,"/")) strcat(dir_data->current_directory,"/"); if(strcmp(tmp->name,".")!=0) strcat(dir_data->current_directory,tmp->name); if(LINUX_S_ISDIR(tmp->st_mode)!=0) { const int res=copy_dir(disk, partition, dir_data, tmp); if(res >=-1) { tmp->status&=~FILE_STATUS_MARKED; copy_ok=1; } else if(res < 0) copy_bad=1; } else if(LINUX_S_ISREG(tmp->st_mode)!=0) { if(dir_data->copy_file(disk, partition, dir_data, tmp) == 0) { tmp->status&=~FILE_STATUS_MARKED; copy_ok=1; } else copy_bad=1; } } dir_data->current_directory[current_directory_namelength]='\0'; } wmove(window,5,0); wclrtoeol(window); if(copy_bad > 0 && copy_ok==0) { if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1)); wprintw(window,"Copy failed!"); } else { if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(2)); if(copy_bad > 0) wprintw(window,"Copy done! (Failed to copy some files)"); else if(copy_ok == 0) wprintw(window,"No file selected"); else wprintw(window,"Copy done!"); } if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); } } break; case 'f': { const char *needle=ask_string_ncurses("Filename to find ? "); if(needle!=NULL && needle[0]!='\0') { file_data_t *pos_org=pos; const int pos_num_org=pos_num; while(strcmp(pos->name, needle)!=0 && pos->next!=NULL) { pos=pos->next; pos_num++; } if(strcmp(pos->name, needle)!=0) { pos=pos_org; pos_num=pos_num_org; } } } break; } if(pos_num<offset) offset=pos_num; if(pos_num>=offset+INTER_DIR) offset=pos_num-INTER_DIR+1; } } while(quit==0 && old_LINES==LINES); } while(quit==0); return -1; }
/** * Output the desired information for one file. */ void printf_entry(GArray *chunks, const wagon_t *id, const attr_set_t *attrs) { int i; for (i = 0; i < chunks->len; i++) { struct fchunk *chunk = &g_array_index(chunks, struct fchunk, i); const char *format = chunk->format->str; switch (chunk->directive) { case 0: #if __GNUC__ >= 7 /* * "format" below is constructed safely, ignore the warning. * Old GCC versions do not like these statements */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-security" #endif printf(format); #if __GNUC__ >= 7 #pragma GCC diagnostic pop #endif break; case 'A': printf_date(chunk, ATTR(attrs, last_access)); break; case 'b': printf(format, ATTR(attrs, blocks)); break; case 'C': printf_date(chunk, ATTR(attrs, last_mdchange)); break; case 'd': printf(format, ATTR(attrs, depth)); break; case 'f': printf(format, ATTR(attrs, name)); break; case 'g': if (global_config.uid_gid_as_numbers) printf(format, ATTR(attrs, gid).num); else printf(format, ATTR(attrs, gid).txt); break; case 'm': printf(format, ATTR(attrs, mode)); break; case 'M': { char mode_str[10]; /* mask + final '\0' */ mode_str[9] = 0; mode_string(ATTR(attrs, mode), mode_str); printf(format, mode_str); } break; case 'n': printf(format, ATTR(attrs, nlink)); break; case 'p': if (prog_options.escaped) printf(format, escape_name(id->fullname)); else printf(format, id->fullname); break; case 's': printf(format, ATTR(attrs, size)); break; case 'T': printf_date(chunk, ATTR(attrs, last_mod)); break; case 'u': if (global_config.uid_gid_as_numbers) printf(format, ATTR(attrs, uid).num); else printf(format, ATTR(attrs, uid).txt); break; case 'Y': { const char *type; if (!ATTR_MASK_TEST(attrs, type)) type = "?"; else type = type2char(ATTR(attrs, type)); printf(format, type); } break; case 'y': { char type; if (!ATTR_MASK_TEST(attrs, type)) type = '?'; else type = type2onechar(ATTR(attrs, type)); printf(format, type); } break; case 'z': printf(format, 0); break; case 'R': /* Robinhood specifiers */ switch (chunk->sub_directive) { case 'C': printf_date(chunk, ATTR(attrs, creation_time)); break; case 'c': printf(format, class_format(ATTR_MASK_TEST(attrs, fileclass) ? ATTR(attrs, fileclass) : NULL)); break; case 'f': { char fid_str[RBH_FID_LEN]; sprintf(fid_str, DFID_NOBRACE, PFID(&id->id)); printf(format, fid_str); } break; case 'm': if (ATTR_MASK_INFO_TEST(attrs, chunk->smi, chunk->rel_sm_info_index)) { switch (chunk->def->db_type) { case DB_UINT: printf(format, *(unsigned int *)SMI_INFO(attrs, chunk->smi, chunk-> rel_sm_info_index)); break; case DB_INT: printf(format, *(int *)SMI_INFO(attrs, chunk->smi, chunk->rel_sm_info_index)); break; case DB_BOOL: printf(format, *(bool *)SMI_INFO(attrs, chunk->smi, chunk->rel_sm_info_index)); break; case DB_TEXT: printf(format, SMI_INFO(attrs, chunk->smi, chunk->rel_sm_info_index)); break; default: break; } } else { switch (chunk->def->db_type) { case DB_UINT: case DB_INT: printf(format, 0); break; case DB_TEXT: printf(format, "[n/a]"); break; default: break; } } break; #ifdef _LUSTRE case 'o': if (ATTR_MASK_TEST(attrs, stripe_items) && (ATTR(attrs, stripe_items).count > 0)) { GString *osts = g_string_new(""); append_stripe_list(osts, &ATTR(attrs, stripe_items), true); printf(format, osts->str); g_string_free(osts, TRUE); } break; case 'p': { char fid_str[RBH_FID_LEN]; sprintf(fid_str, DFID_NOBRACE, PFID(&ATTR(attrs, parent_id))); printf(format, fid_str); break; } #endif case SUB_DIRECTIVE_STATUS: { unsigned int smi_index = chunk->smi->smi_index; if (ATTR_MASK_STATUS_TEST(attrs, smi_index)) printf(format, STATUS_ATTR(attrs, smi_index)); else printf(format, "[n/a]"); break; } } break; } } }
/* * Read a tar file and extract or list the specified files within it. * If the list is empty than all files are extracted or listed. */ static int readTarFile(int tarFd, int extractFlag, int listFlag, int tostdoutFlag, int verboseFlag, char** extractList, char** excludeList) { int status; int errorFlag=FALSE; int skipNextHeaderFlag=FALSE; TarHeader rawHeader; TarInfo header; /* Read the tar file, and iterate over it one file at a time */ while ( (status = full_read(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) { /* Try to read the header */ if ( readTarHeader(&rawHeader, &header) == FALSE ) { if ( *(header.name) == '\0' ) { goto endgame; } else { errorFlag=TRUE; error_msg("Bad tar header, skipping"); continue; } } if ( *(header.name) == '\0' ) continue; header.tarFd = tarFd; /* Skip funky extra GNU headers that precede long files */ if ( (header.type == GNULONGNAME) || (header.type == GNULONGLINK) ) { skipNextHeaderFlag=TRUE; if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE) errorFlag = TRUE; continue; } if ( skipNextHeaderFlag == TRUE ) { skipNextHeaderFlag=FALSE; error_msg(name_longer_than_foo, NAME_SIZE); if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE) errorFlag = TRUE; continue; } #if defined BB_FEATURE_TAR_EXCLUDE if (exclude_file(excludeList, header.name)) { /* There are not the droids you're looking for, move along */ /* If it is a regular file, pretend to extract it with * the extractFlag set to FALSE, so the junk in the tarball * is properly skipped over */ if ( header.type==REGTYPE || header.type==REGTYPE0 ) { if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE) errorFlag = TRUE; } continue; } #endif if (!extract_file(extractList, header.name)) { /* There are not the droids you're looking for, move along */ /* If it is a regular file, pretend to extract it with * the extractFlag set to FALSE, so the junk in the tarball * is properly skipped over */ if ( header.type==REGTYPE || header.type==REGTYPE0 ) { if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE) errorFlag = TRUE; } continue; } if (listFlag == TRUE) { /* Special treatment if the list (-t) flag is on */ if (verboseFlag == TRUE) { int len, len1; char buf[35]; struct tm *tm = localtime (&(header.mtime)); len=printf("%s ", mode_string(header.mode)); my_getpwuid(buf, header.uid); if (! *buf) len+=printf("%d", header.uid); else len+=printf("%s", buf); my_getgrgid(buf, header.gid); if (! *buf) len+=printf("/%-d ", header.gid); else len+=printf("/%-s ", buf); if (header.type==CHRTYPE || header.type==BLKTYPE) { len1=snprintf(buf, sizeof(buf), "%ld,%-ld ", header.devmajor, header.devminor); } else { len1=snprintf(buf, sizeof(buf), "%lu ", (long)header.size); } /* Jump through some hoops to make the columns match up */ for(;(len+len1)<31;len++) printf(" "); printf(buf); /* Use ISO 8610 time format */ if (tm) { printf ("%04d-%02d-%02d %02d:%02d:%02d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); } } printf("%s", header.name); if (verboseFlag == TRUE) { if (header.type==LNKTYPE) /* If this is a link, say so */ printf(" link to %s", header.linkname); else if (header.type==SYMTYPE) printf(" -> %s", header.linkname); } printf("\n"); } /* List contents if we are supposed to do that */ if (verboseFlag == TRUE && extractFlag == TRUE) { /* Now the normal listing */ FILE *vbFd = stdout; if (tostdoutFlag == TRUE) // If the archive goes to stdout, verbose to stderr vbFd = stderr; fprintf(vbFd, "%s\n", header.name); } /* Remove files if we would overwrite them */ if (extractFlag == TRUE && tostdoutFlag == FALSE) unlink(header.name); /* If we got here, we can be certain we have a legitimate * header to work with. So work with it. */ switch ( header.type ) { case REGTYPE: case REGTYPE0: /* If the name ends in a '/' then assume it is * supposed to be a directory, and fall through */ if (!last_char_is(header.name,'/')) { if (tarExtractRegularFile(&header, extractFlag, tostdoutFlag)==FALSE) errorFlag=TRUE; break; } case DIRTYPE: if (tarExtractDirectory( &header, extractFlag, tostdoutFlag)==FALSE) errorFlag=TRUE; break; case LNKTYPE: if (tarExtractHardLink( &header, extractFlag, tostdoutFlag)==FALSE) errorFlag=TRUE; break; case SYMTYPE: if (tarExtractSymLink( &header, extractFlag, tostdoutFlag)==FALSE) errorFlag=TRUE; break; case CHRTYPE: case BLKTYPE: case FIFOTYPE: if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE) errorFlag=TRUE; break; #if 0 /* Handled earlier */ case GNULONGNAME: case GNULONGLINK: skipNextHeaderFlag=TRUE; break; #endif default: error_msg("Unknown file type '%c' in tar file", header.type); close( tarFd); return( FALSE); } } close(tarFd); if (status > 0) { /* Bummer - we read a partial header */ perror_msg("Error reading tar file"); return ( FALSE); } else if (errorFlag==TRUE) { error_msg( "Error exit delayed from previous errors"); return( FALSE); } else return( status); /* Stuff to do when we are done */ endgame: close( tarFd); if ( *(header.name) == '\0' ) { if (errorFlag==TRUE) error_msg( "Error exit delayed from previous errors"); else return( TRUE); } return( FALSE); }