Changeset 3878 in MondoRescue for branches/3.3/mondo/src/common/libmondo-filelist.c
- Timestamp:
- Mar 8, 2024, 12:15:10 PM (4 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mondo/src/common/libmondo-filelist.c
r3871 r3878 60 60 extern char *g_getfacl; 61 61 extern char *g_getfattr; 62 63 64 65 /** 66 * Chop the filelist into sets. 67 * Each fileset is a list of files whose total (uncompressed) size is usually 68 * about X KB. Files bigger than 8X KB are placed in a "biggielist"; they will 69 * be sliced and compressed separately from the regular files. 70 * 71 * @param filelist The big filelist (filelist.full) to chop up. 72 * @param outdir The directory to place the files (filelist.N where N is 73 * an integer, biggielist.txt, and LAST-FILELIST-NUMBER) created 74 * @param maxsetsizeK Optimal size of a fileset (X above). 75 * @return number of errors encountered (0 for success). 76 */ 77 int chop_filelist(char *filelist, char *outdir, long maxsetsizeK) 78 { 79 /*@ long ****************************************/ 80 long lino = 0; 81 // A big file has more than 64 MB of real content 82 long curr_set_size; 83 long noof_lines; 84 long siz; 85 86 /*@ int **************************************** */ 87 int i; 88 long curr_set_no; 89 90 /*@ buffers ************************************* */ 91 char *outfname = NULL; 92 char *biggie_fname = NULL; 93 char *incoming = NULL; 94 char *tmp = NULL; 95 96 /*@ pointers *********************************** */ 97 FILE *fin; 98 FILE *fout; 99 FILE *fbig; 100 101 /*@ structures ********************************* */ 102 struct stat buf; 103 int err = 0; 104 105 assert_string_is_neither_NULL_nor_zerolength(filelist); 106 assert_string_is_neither_NULL_nor_zerolength(outdir); 107 assert(maxsetsizeK > 0); 108 109 log_it("filelist=%s;", filelist); 110 open_evalcall_form("Dividing filelist into sets"); 111 noof_lines = count_lines_in_file(filelist); 112 if (!(fin = fopen(filelist, "r"))) { 113 log_OS_error("Cannot openin filelist"); 114 return (0); 115 } 116 curr_set_no = 0; 117 curr_set_size = 0; 118 mr_asprintf(outfname, "%s/filelist.%ld", outdir, curr_set_no); 119 mr_asprintf(biggie_fname, "%s/biggielist.txt", outdir); 120 log_it("outfname=%s; biggie_fname=%s", outfname, biggie_fname); 121 if (!(fbig = fopen(biggie_fname, "w"))) { 122 log_OS_error("Cannot openout biggie_fname"); 123 err++; 124 mr_free(outfname); 125 mr_free(biggie_fname); 126 return (curr_set_no + 1); 127 } 128 if (!(fout = fopen(outfname, "w"))) { 129 log_OS_error("Cannot openout outfname"); 130 err++; 131 mr_free(outfname); 132 mr_free(biggie_fname); 133 return (curr_set_no + 1); 134 } 135 136 mr_getline(incoming, fin); 137 while (!feof(fin)) { 138 lino++; 139 i = strlen(incoming) - 1; 140 if (i < 0) { 141 i = 0; 142 } 143 if (incoming[i] < 32) { 144 incoming[i] = '\0'; 145 } 146 if (!strncmp(incoming, "/dev/", 5)) { 147 siz = 1; 148 } else if (lstat(incoming, &buf) != 0) { 149 siz = 0; 150 } else { 151 // blocks are 512 bytes long - cf man 2 stat - Pass to the previous unit (MB => kB e.g.) 152 // use blocks instead of size to allow sparse file correct handling as much as possible 153 siz = (long) ((buf.st_blocks*512) >> 10); 154 } 155 if (siz > g_max_biggie_size) { 156 log_msg(10, "Adding %s to big files (size = %ld)", incoming, siz); 157 fprintf(fbig, "%s\n", incoming); 158 } else { 159 curr_set_size += siz; 160 log_msg(10, "Adding %s to filelist %d (size = %ld)", incoming, curr_set_no, siz); 161 fprintf(fout, "%s\n", incoming); 162 if (curr_set_size > maxsetsizeK) { 163 paranoid_fclose(fout); 164 sort_file(outfname); 165 mr_free(outfname); 166 curr_set_no++; 167 curr_set_size = 0; 168 169 mr_asprintf(outfname, "%s/filelist.%ld", outdir, curr_set_no); 170 if (!(fout = fopen(outfname, "w"))) { 171 log_OS_error("Unable to openout outfname"); 172 err++; 173 mr_free(outfname); 174 mr_free(biggie_fname); 175 mr_free(incoming); 176 return (curr_set_no + 1); 177 } 178 update_evalcall_form((int) (lino * 100 / noof_lines)); 179 } 180 } 181 mr_free(incoming); 182 mr_getline(incoming, fin); 183 } 184 mr_free(incoming); 185 186 paranoid_fclose(fin); 187 paranoid_fclose(fout); 188 paranoid_fclose(fbig); 189 190 if (length_of_file(outfname) <= 2) { 191 unlink(outfname); 192 g_noof_sets--; 193 } 194 g_noof_sets = curr_set_no; 195 sort_file(outfname); 196 mr_free(outfname); 197 198 sort_file(biggie_fname); 199 mr_free(biggie_fname); 200 201 mr_asprintf(outfname, "%s/LAST-FILELIST-NUMBER", outdir); 202 mr_asprintf(tmp, "%ld", curr_set_no); 203 if (write_one_liner_data_file(outfname, tmp)) { 204 log_OS_error 205 ("Unable to echo write one-liner to LAST-FILELIST-NUMBER"); 206 err = 1; 207 } 208 mr_free(tmp); 209 mr_free(outfname); 210 211 if (curr_set_no == 0) { 212 log_msg(1, "Only one fileset. Fine."); 213 } else { 214 log_msg(1, "Filelist divided into %ld sets", curr_set_no + 1); 215 } 216 close_evalcall_form(); 217 /* This is to work around an obscure bug in Newt; open a form, close it, 218 carry on... I don't know why it works but it works. If you don't do this 219 then update_progress_form() won't show the "time taken / time remaining" 220 line. The bug only crops up AFTER the call to chop_filelist(). Weird. */ 221 if (!g_text_mode) { 222 open_progress_form("", "", "", "", 100); 223 newtPopHelpLine(); 224 newtFormDestroy(g_progressForm); 225 newtPopWindow(); 226 } 227 return (err ? 0 : curr_set_no + 1); 228 } 229 62 230 63 231 … … 184 352 185 353 186 /**187 * Chop the filelist into sets.188 * Each fileset is a list of files whose total (uncompressed) size is usually189 * about X KB. Files bigger than 8X KB are placed in a "biggielist"; they will190 * be sliced and compressed separately from the regular files.191 *192 * @param filelist The big filelist (filelist.full) to chop up.193 * @param outdir The directory to place the files (filelist.N where N is194 * an integer, biggielist.txt, and LAST-FILELIST-NUMBER) created195 * @param maxsetsizeK Optimal size of a fileset (X above).196 * @return number of errors encountered (0 for success).197 */198 int chop_filelist(char *filelist, char *outdir, long maxsetsizeK)199 {200 /*@ long ****************************************/201 long lino = 0;202 // A big file has more than 64 MB of real content203 long curr_set_size;204 long noof_lines;205 long siz;206 207 /*@ int **************************************** */208 int i;209 long curr_set_no;210 211 /*@ buffers ************************************* */212 char *outfname = NULL;213 char *biggie_fname = NULL;214 char *incoming = NULL;215 char *tmp = NULL;216 217 /*@ pointers *********************************** */218 FILE *fin;219 FILE *fout;220 FILE *fbig;221 222 /*@ structures ********************************* */223 struct stat buf;224 int err = 0;225 226 assert_string_is_neither_NULL_nor_zerolength(filelist);227 assert_string_is_neither_NULL_nor_zerolength(outdir);228 assert(maxsetsizeK > 0);229 230 log_it("filelist=%s;", filelist);231 open_evalcall_form("Dividing filelist into sets");232 noof_lines = count_lines_in_file(filelist);233 if (!(fin = fopen(filelist, "r"))) {234 log_OS_error("Cannot openin filelist");235 return (0);236 }237 curr_set_no = 0;238 curr_set_size = 0;239 mr_asprintf(outfname, "%s/filelist.%ld", outdir, curr_set_no);240 mr_asprintf(biggie_fname, "%s/biggielist.txt", outdir);241 log_it("outfname=%s; biggie_fname=%s", outfname, biggie_fname);242 if (!(fbig = fopen(biggie_fname, "w"))) {243 log_OS_error("Cannot openout biggie_fname");244 err++;245 mr_free(outfname);246 mr_free(biggie_fname);247 return (curr_set_no + 1);248 }249 if (!(fout = fopen(outfname, "w"))) {250 log_OS_error("Cannot openout outfname");251 err++;252 mr_free(outfname);253 mr_free(biggie_fname);254 return (curr_set_no + 1);255 }256 257 mr_getline(incoming, fin);258 while (!feof(fin)) {259 lino++;260 i = strlen(incoming) - 1;261 if (i < 0) {262 i = 0;263 }264 if (incoming[i] < 32) {265 incoming[i] = '\0';266 }267 if (!strncmp(incoming, "/dev/", 5)) {268 siz = 1;269 } else if (lstat(incoming, &buf) != 0) {270 siz = 0;271 } else {272 // blocks are 512 bytes long - cf man 2 stat - Pass to the previous unit (MB => kB e.g.)273 // use blocks instead of size to allow sparse file correct handling as much as possible274 siz = (long) ((buf.st_blocks*512) >> 10);275 }276 if (siz > g_max_biggie_size) {277 log_msg(10, "Adding %s to big files (size = %ld)", incoming, siz);278 fprintf(fbig, "%s\n", incoming);279 } else {280 curr_set_size += siz;281 log_msg(10, "Adding %s to filelist %d (size = %ld)", incoming, curr_set_no, siz);282 fprintf(fout, "%s\n", incoming);283 if (curr_set_size > maxsetsizeK) {284 paranoid_fclose(fout);285 sort_file(outfname);286 mr_free(outfname);287 curr_set_no++;288 curr_set_size = 0;289 290 mr_asprintf(outfname, "%s/filelist.%ld", outdir, curr_set_no);291 if (!(fout = fopen(outfname, "w"))) {292 log_OS_error("Unable to openout outfname");293 err++;294 mr_free(outfname);295 mr_free(biggie_fname);296 mr_free(incoming);297 return (curr_set_no + 1);298 }299 update_evalcall_form((int) (lino * 100 / noof_lines));300 }301 }302 mr_free(incoming);303 mr_getline(incoming, fin);304 }305 mr_free(incoming);306 307 paranoid_fclose(fin);308 paranoid_fclose(fout);309 paranoid_fclose(fbig);310 311 if (length_of_file(outfname) <= 2) {312 unlink(outfname);313 g_noof_sets--;314 }315 g_noof_sets = curr_set_no;316 sort_file(outfname);317 mr_free(outfname);318 319 sort_file(biggie_fname);320 mr_free(biggie_fname);321 322 mr_asprintf(outfname, "%s/LAST-FILELIST-NUMBER", outdir);323 mr_asprintf(tmp, "%ld", curr_set_no);324 if (write_one_liner_data_file(outfname, tmp)) {325 log_OS_error326 ("Unable to echo write one-liner to LAST-FILELIST-NUMBER");327 err = 1;328 }329 mr_free(tmp);330 mr_free(outfname);331 332 if (curr_set_no == 0) {333 log_msg(1, "Only one fileset. Fine.");334 } else {335 log_msg(1, "Filelist divided into %ld sets", curr_set_no + 1);336 }337 close_evalcall_form();338 /* This is to work around an obscure bug in Newt; open a form, close it,339 carry on... I don't know why it works but it works. If you don't do this340 then update_progress_form() won't show the "time taken / time remaining"341 line. The bug only crops up AFTER the call to chop_filelist(). Weird. */342 if (!g_text_mode) {343 open_progress_form("", "", "", "", 100);344 newtPopHelpLine();345 newtFormDestroy(g_progressForm);346 newtPopWindow();347 }348 return (err ? 0 : curr_set_no + 1);349 }350 351 352 353 354 354 355 355 /** … … 967 967 } 968 968 return; 969 }970 971 972 973 974 /**975 * Reset the filelist to the state it was when it was loaded. This does not976 * touch the file on disk.977 * @param filelist The filelist tree structure.978 */979 void reload_filelist(struct s_node *filelist)980 {981 assert(filelist != NULL);982 toggle_node_selection(filelist, FALSE);983 toggle_path_expandability(filelist, "/", FALSE);984 toggle_all_root_dirs_on(filelist);985 }986 987 988 989 /**990 * Save a filelist tree structure to disk.991 * @param filelist The filelist tree structure to save.992 * @param outfname Where to save it.993 */994 void save_filelist(struct s_node *filelist, char *outfname)995 {996 /*@ int ********************************************************* */997 static int percentage;998 static int depth = 0;999 1000 /*@ buffers ***************************************************** */1001 static char str[MAX_STR_LEN];1002 1003 /*@ structures ************************************************** */1004 struct s_node *node;1005 1006 /*@ pointers **************************************************** */1007 static FILE *fout = NULL;1008 1009 /*@ long ******************************************************** */1010 static long lines_in_filelist = 0;1011 static long lino = 0;1012 1013 /*@ end vars *************************************************** */1014 1015 assert(filelist != NULL);1016 assert(outfname != NULL); // will be zerolength if save_filelist() is called by itself1017 if (depth == 0) {1018 log_to_screen("Saving filelist");1019 if (!(fout = fopen(outfname, "w"))) {1020 fatal_error("Cannot openout/save filelist");1021 }1022 lines_in_filelist = g_original_noof_lines_in_filelist; /* set by load_filelist() */1023 open_evalcall_form("Saving selection to disk");1024 }1025 for (node = filelist; node != NULL; node = node->right) {1026 str[depth] = node->ch;1027 log_msg(5, "depth=%d ch=%c", depth, node->ch);1028 if (!node->ch) {1029 // if (node->selected)1030 // {1031 fprintf(fout, "%s\n", str);1032 // }1033 if (!(++lino % 1111)) {1034 percentage = (int) (lino * 100 / lines_in_filelist);1035 update_evalcall_form(percentage);1036 }1037 }1038 if (node->down) {1039 depth++;1040 save_filelist(node->down, "");1041 depth--;1042 }1043 }1044 if (depth == 0) {1045 paranoid_fclose(fout);1046 close_evalcall_form();1047 log_it("Finished saving filelist");1048 }1049 969 } 1050 970 … … 1251 1171 } 1252 1172 1173 1174 1175 1176 /** 1177 * Reset the filelist to the state it was when it was loaded. This does not 1178 * touch the file on disk. 1179 * @param filelist The filelist tree structure. 1180 */ 1181 void reload_filelist(struct s_node *filelist) 1182 { 1183 assert(filelist != NULL); 1184 toggle_node_selection(filelist, FALSE); 1185 toggle_path_expandability(filelist, "/", FALSE); 1186 toggle_all_root_dirs_on(filelist); 1187 } 1188 1189 1190 1191 /** 1192 * Save a filelist tree structure to disk. 1193 * @param filelist The filelist tree structure to save. 1194 * @param outfname Where to save it. 1195 */ 1196 void save_filelist(struct s_node *filelist, char *outfname) 1197 { 1198 /*@ int ********************************************************* */ 1199 static int percentage; 1200 static int depth = 0; 1201 1202 /*@ buffers ***************************************************** */ 1203 static char str[MAX_STR_LEN]; 1204 1205 /*@ structures ************************************************** */ 1206 struct s_node *node; 1207 1208 /*@ pointers **************************************************** */ 1209 static FILE *fout = NULL; 1210 1211 /*@ long ******************************************************** */ 1212 static long lines_in_filelist = 0; 1213 static long lino = 0; 1214 1215 /*@ end vars *************************************************** */ 1216 1217 assert(filelist != NULL); 1218 assert(outfname != NULL); // will be zerolength if save_filelist() is called by itself 1219 if (depth == 0) { 1220 log_to_screen("Saving filelist"); 1221 if (!(fout = fopen(outfname, "w"))) { 1222 fatal_error("Cannot openout/save filelist"); 1223 } 1224 lines_in_filelist = g_original_noof_lines_in_filelist; /* set by load_filelist() */ 1225 open_evalcall_form("Saving selection to disk"); 1226 } 1227 for (node = filelist; node != NULL; node = node->right) { 1228 str[depth] = node->ch; 1229 log_msg(5, "depth=%d ch=%c", depth, node->ch); 1230 if (!node->ch) { 1231 // if (node->selected) 1232 // { 1233 fprintf(fout, "%s\n", str); 1234 // } 1235 if (!(++lino % 1111)) { 1236 percentage = (int) (lino * 100 / lines_in_filelist); 1237 update_evalcall_form(percentage); 1238 } 1239 } 1240 if (node->down) { 1241 depth++; 1242 save_filelist(node->down, ""); 1243 depth--; 1244 } 1245 } 1246 if (depth == 0) { 1247 paranoid_fclose(fout); 1248 close_evalcall_form(); 1249 log_it("Finished saving filelist"); 1250 } 1251 } 1253 1252 1254 1253
Note:
See TracChangeset
for help on using the changeset viewer.