Changeset 3879 in MondoRescue for branches/3.3/mondo/src/common/libmondo-cli.c
- Timestamp:
- Mar 9, 2024, 3:10:04 AM (2 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mondo/src/common/libmondo-cli.c
r3875 r3879 15 15 #include "mr_str.h" 16 16 #include "mondostructures.h" 17 #include "libmondo-cli-EXT.h" 17 #include "libmondo-string-EXT.h" 18 #include "libmondo-files-EXT.h" 19 #include "libmondo-stream-EXT.h" 20 #include "libmondo-devices-EXT.h" 21 #include "libmondo-fork-EXT.h" 22 #include "libmondo-fifo-EXT.h" 18 23 #include "newt-specific-EXT.h" 19 #include "libmondo.h"20 24 21 25 extern int g_loglevel; … … 61 65 62 66 long g_max_biggie_size = BIGGIEMAXSIZE; 63 64 /**65 * @addtogroup cliGroup66 * @{67 */68 /**69 * Populate @p bkpinfo from the command-line parameters stored in @p argc and @p argv.70 * @param argc The argument count, including the program name; @p argc passed to main().71 * @param argv The argument vector; @p argv passed to main().72 * @param bkpinfo The backup information structure to populate.73 * @return The number of problems with the command line (0 for success).74 */75 int76 handle_incoming_parameters(int argc, char *argv[])77 {78 /*@ int *** */79 int res = 0;80 int retval = 0;81 int i = 0;82 83 /*@ buffers *************** */84 char flag_val[128][MAX_STR_LEN];85 bool flag_set[128];86 87 for (i = 0; i < 128; i++) {88 flag_val[i][0] = '\0';89 flag_set[i] = FALSE;90 }91 bkpinfo->media_size = 650; /* default */92 res = retrieve_switches_from_command_line(argc, argv, flag_val, flag_set);93 retval += res;94 if (!retval) {95 res = process_switches(flag_val, flag_set);96 retval += res;97 }98 99 log_msg(3, "Switches:-");100 for (i = 0; i < 128; i++) {101 if (flag_set[i]) {102 log_msg(3, "-%c %s", i, flag_val[i]);103 }104 }105 bkpinfo->boot_type = mr_boot_type();106 107 return (retval);108 }109 67 110 68 … … 131 89 } 132 90 91 133 92 /** 134 * Process mondoarchive's command-line switches. 135 * @param bkpinfo The backup information structure to populate. 136 * @param flag_val An array of the argument passed to each switch (the letter is the index). 137 * If a switch is not set or has no argument, the field in @p flag_val doesn't matter. 138 * @param flag_set An array of <tt>bool</tt>s indexed by switch letter: TRUE if it's set, 139 * FALSE if it's not. 140 * @return The number of problems with the switches, or 0 for success. 141 * @bug Maybe include a list of all switches (inc. intentionally undocumented ones not in the manual!) here? 93 * Print a not-so-helpful help message and exit. 142 94 */ 143 int 144 process_switches(char flag_val[128][MAX_STR_LEN], bool flag_set[128]) 95 void help_screen() 145 96 { 146 147 /*@ ints *** */ 148 int i = 0; 149 int retval = 0; 150 151 /*@ buffers ** */ 152 char *tmp = NULL; 153 char *tmp1 = NULL; 154 char *tmp2 = NULL; 155 char *psz = NULL; 156 char *p = NULL; 157 char *q = NULL; 158 char *q2 = NULL; 159 160 long itbs = 0L; 161 162 struct stat buf; 163 164 malloc_string(tmp); 165 166 assert(bkpinfo != NULL); 167 assert(flag_val != NULL); 168 assert(flag_set != NULL); 169 170 bkpinfo->internal_tape_block_size = DEFAULT_INTERNAL_TAPE_BLOCK_SIZE; 171 172 /* compulsory */ 173 i = flag_set['c'] + flag_set['i'] + flag_set['n'] + 174 flag_set['t'] + flag_set['u'] + flag_set['r'] + 175 flag_set['w'] + flag_set['C'] + flag_set['U']; 176 if ((i == 0) && (! bkpinfo->restore_data)) { 177 retval++; 178 log_to_screen("You must specify the media type\n"); 179 } 180 if (i > 1) { 181 retval++; 182 log_to_screen("Please specify only one media type\n"); 183 } 184 185 if (flag_set['K']) { 186 g_loglevel = atoi(flag_val['K']); 187 log_msg(1,"Loglevel forced to %d",g_loglevel); 188 if (g_loglevel < 3) { 189 g_loglevel = 3; 190 } 191 } 192 193 if ((flag_set['L'] && flag_set['0']) && (! bkpinfo->restore_data)) { 194 retval++; 195 log_to_screen("You cannot have 'no compression' _and_ LZOP.\n"); 196 } 197 if (! bkpinfo->restore_data) { 198 bkpinfo->backup_data = flag_set['O']; 199 } 200 bkpinfo->verify_data = flag_set['V']; 201 202 if (flag_set['I'] && !bkpinfo->backup_data) { 203 log_to_screen("-I switch is ignored if just verifying"); 204 } 205 if (flag_set['E'] && !bkpinfo->backup_data) { 206 log_to_screen("-E switch is ignored if just verifying"); 207 } 208 209 if ((tmp = find_home_of_exe("afio")) == NULL) { 210 mr_free(tmp); 211 if ((tmp = find_home_of_exe("star")) != NULL) { 212 mr_free(tmp); 213 flag_set['R'] = TRUE; 214 log_msg(1, "Using star instead of afio"); 215 } else { 216 mr_free(tmp); 217 fatal_error("Neither afio nor star is installed. Please install at least one."); 218 } 219 } 220 221 if (flag_set['R']) { 222 bkpinfo->use_star = TRUE; 223 if (flag_set['L']) { 224 fatal_error("You may not use star and lzop at the same time."); 225 } 226 if ((tmp = find_home_of_exe("star")) == NULL) { 227 mr_free(tmp); 228 fatal_error("Please install 'star' if you are going to use -R. Thanks."); 229 } 230 mr_free(tmp); 231 } 232 233 if ((flag_set['W']) && (! bkpinfo->restore_data)) { 234 bkpinfo->nonbootable_backup = TRUE; 235 log_to_screen("Warning - you have opted for non-bootable backup"); 236 if (flag_set['f'] || flag_set['l']) { 237 log_to_screen 238 ("You don't need to specify bootloader or bootdevice"); 239 } 240 } 241 242 if (flag_set['I']) { 243 if (flag_val['I'][0] == '-') { 244 retval++; 245 log_to_screen("Please supply a sensible value with '-I'\n"); 246 } 247 if (!strcmp(flag_val['I'],"/")) { 248 log_msg(2, "'/' is pleonastic."); 249 } 250 if (bkpinfo->include_paths && bkpinfo->include_paths[0]) { 251 mr_strcat(bkpinfo->include_paths, "|"); 252 } 253 254 mr_asprintf(tmp1, "%s", flag_val['I']); 255 p = tmp1; 256 q = tmp1; 257 258 /* Cut the flag_val['I'] in parts containing all paths to test them */ 259 while (p != NULL) { 260 q = strchr(p, '|'); 261 if (q != NULL) { 262 *q = '\0'; 263 if ((stat(p, &buf) != 0) && (! bkpinfo->restore_data)) { 264 log_msg(1, "ERROR ! %s doesn't exist", p); 265 fatal_error("ERROR ! You specified a directory to include which doesn't exist"); 266 } 267 p = q+1 ; 268 } else { 269 if ((stat(p, &buf) != 0) && (! bkpinfo->restore_data)) { 270 log_msg(1, "ERROR ! %s doesn't exist", p); 271 fatal_error("ERROR ! You specified a directory to include which doesn't exist"); 272 } 273 p = NULL; 274 } 275 } 276 mr_free(tmp1); 277 mr_make_devlist_from_pathlist(flag_val['I'], 'I'); 278 log_msg(4, "Finished with the -I option"); 279 } 280 281 if (g_kernel_version >= 2.6 && !flag_set['d'] && (flag_set['c'] || flag_set['w']) && (! bkpinfo->restore_data)) { 282 fatal_error("If you are using the 2.6.x kernel, please specify the CD-R(W) device."); 283 } 284 285 286 if (flag_set['J']) { 287 if (flag_set['I']) { 288 retval++; 289 log_to_screen("Please do not use -J in combination with -I. If you want to make a list of files to backup, that's fine, use -J <filename> but please don't muddy the waters by combining -J with -I. Thanks. :-)"); 290 } 291 bkpinfo->make_filelist = FALSE; 292 mr_asprintf(bkpinfo->include_paths, "%s", flag_val['J']); 293 } 294 295 if ((flag_set['c'] || flag_set['w'] || flag_set['C'] || flag_set['r']) && (! bkpinfo->restore_data)) { 296 if (system("which cdrecord > /dev/null 2> /dev/null") && system("which dvdrecord > /dev/null 2> /dev/null")) { 297 fatal_error("Please install dvdrecord/cdrecord and try again."); 298 } 299 if (flag_set['C']) { 300 bkpinfo->cdrw_speed = atoi(flag_val['C']); 301 if (bkpinfo->cdrw_speed < 1) { 302 fatal_error("You specified a silly speed for a CD-R[W] drive"); 303 } 304 if (!flag_set['L']) { 305 log_to_screen("You must use -L with -C. Therefore I am setting it for you."); 306 flag_set['L'] = 1; 307 flag_val['L'][0] = '\0'; 308 } 309 } else { 310 log_msg(3, "flag_val['c'] = %s", flag_val['c']); 311 log_msg(3, "flag_val['w'] = %s", flag_val['w']); 312 if (flag_set['c']) { 313 bkpinfo->cdrw_speed = atoi(flag_val['c']); 314 } else if (flag_set['w']) { 315 bkpinfo->cdrw_speed = atoi(flag_val['w']); 316 } else if (flag_set['r']) { 317 bkpinfo->cdrw_speed = 1; /*atoi(flag_val['r']); */ 318 } 319 320 if (bkpinfo->cdrw_speed < 1) { 321 fatal_error("You specified a silly speed for a CD-R[W] drive"); 322 } 323 } 324 } 325 326 if ((flag_set['t'] && !flag_set['d']) && (! bkpinfo->restore_data)) { 327 log_it("Hmm! No tape drive specified. Let's see what we can do."); 328 if ((bkpinfo->media_device = find_tape_device()) == NULL) { 329 fatal_error("Tape device not specified and I couldn't find it either. Please use option -d"); 330 } 331 flag_set['d'] = TRUE; 332 log_to_screen("You didn't specify a tape streamer device. I'm assuming %s", bkpinfo->media_device); 333 } 334 335 if (flag_set['U']) // USB 336 { 337 if (! flag_set['d']) { 338 fatal_error("You need to specify a device file with -d for bootable USB device usage"); 339 } 340 if ((!flag_set['s']) && (! bkpinfo->restore_data)) { 341 fatal_error("You did not specify a size (-s) for your USB device. Aborting"); 342 } 343 } 344 345 if (flag_set['r']) // DVD 346 { 347 if (flag_set['m']) { 348 fatal_error("Manual CD tray (-m) not yet supported in conjunction w/ DVD drives. Drop -m."); 349 } 350 if (!flag_set['d']) { 351 if ((bkpinfo->media_device = find_optical_device()) != NULL) { 352 flag_set['d'] = TRUE; 353 log_to_screen("I guess DVD drive is at %s", bkpinfo->media_device); 354 } 355 } 356 if (strchr(bkpinfo->media_device, ',')) { 357 fatal_error("Please don't give a SCSI node. Give a _device_, preferably a /dev entry, for the parameter of the -d flag."); 358 } 359 if (! bkpinfo->restore_data) { 360 if (!flag_set['s']) { 361 sprintf(flag_val['s'], "%d", DEFAULT_DVD_DISK_SIZE); // 4.7 salesman's GB = 4.482 real GB = 4582 MB 362 strcat(flag_val['s'], "m"); 363 log_to_screen("You did not specify a size (-s) for DVD. I'm guessing %s.", flag_val['s']); 364 flag_set['s'] = 1; 365 } 366 } 367 } 368 369 if (flag_set['t'] || flag_set['u']) { /* tape size */ 370 if (strchr(flag_val['d'], ',')) { 371 fatal_error("Please don't give a SCSI node. Give a _device_, preferably a /dev entry, for the parameter of the -d flag."); 372 } 373 if ((flag_set['O']) && (! bkpinfo->restore_data)) { 374 if (flag_set['s']) { 375 if (flag_set['t']) { 376 fatal_error("For the moment, please don't specify a tape size. Mondo should handle end-of-tape gracefully anyway."); 377 } 378 if (process_the_s_switch(flag_val['s'])) { 379 fatal_error("Bad -s switch"); 380 } 381 } else if (flag_set['u'] || flag_set['t']) { 382 bkpinfo->media_size = 0; 383 } else { 384 retval++; 385 log_to_screen("Tape size not specified.\n"); 386 } 387 } 388 } else if (! bkpinfo->restore_data) { /* CD|USB size */ 389 if (flag_set['s']) { 390 if (process_the_s_switch(flag_val['s'])) { 391 fatal_error("Bad -s switch"); 392 } 393 } 394 if (flag_set['w']) { 395 bkpinfo->wipe_media_first = TRUE; 396 } /* CD-RW */ 397 } 398 399 if (flag_set['n']) { 400 mr_asprintf(bkpinfo->netfs_mount, "%s", flag_val['n']); 401 if (!flag_set['d']) { 402 mr_asprintf(bkpinfo->netfs_remote_dir, "/"); 403 mr_asprintf(bkpinfo->isodir, "%s", "."); 404 } 405 /* test for protocol */ 406 p = strstr(bkpinfo->netfs_mount, "://"); 407 if (p == NULL) { 408 /* protocol not found assuming NFS for compatibility */ 409 mr_asprintf(q,"nfs"); 410 411 p = strchr(bkpinfo->netfs_mount, ':'); 412 if (p == NULL) { 413 fatal_error("No protocol specified for remote share mount, nor any old NFS syntax found.\nPlease do man mondoarchive as syntax changed"); 414 } 415 /* p points on to the string server:/path */ 416 p = bkpinfo->netfs_mount; 417 418 } else { 419 /* Isolate the protocol */ 420 *p = '\0'; 421 mr_asprintf(q,"%s",bkpinfo->netfs_mount); 422 423 /* Skip proto now */ 424 p++; 425 p++; 426 p++; 427 } 428 /* whatever done before proto is pointed to by q */ 429 bkpinfo->netfs_proto = q; 430 431 /* p points on to the string server:/path */ 432 /* Store the 2 values */ 433 q2 = bkpinfo->netfs_mount; 434 mr_asprintf(bkpinfo->netfs_mount, "%s", p); 435 mr_free(q2); 436 437 /* test if we specified a user */ 438 p = strchr(bkpinfo->netfs_mount, '@'); 439 if (p != NULL) { 440 /* User found. Store the 2 values */ 441 mr_asprintf(bkpinfo->netfs_user, "%s", bkpinfo->netfs_mount); 442 p = strchr(bkpinfo->netfs_user, '@'); 443 *p = '\0'; 444 p = strchr(bkpinfo->netfs_mount, '@'); 445 p++; 446 /* new netfs mount */ 447 q2 = bkpinfo->netfs_mount; 448 mr_asprintf(bkpinfo->netfs_mount, "%s", p); 449 mr_free(q2); 450 } 451 if (bkpinfo->netfs_user != NULL) { 452 mr_asprintf(tmp1, "mount | grep -E \"^[a-z]*#*[%s@]*%s[/]* .*\" | cut -d' ' -f3", bkpinfo->netfs_user, bkpinfo->netfs_mount); 453 } else { 454 mr_asprintf(tmp1, "mount | grep -E \"^[a-z]*#*%s[/]* .*\" | cut -d' ' -f3", bkpinfo->netfs_mount); 455 } 456 mr_free(bkpinfo->isodir); 457 bkpinfo->isodir = call_program_and_get_last_line_of_output(tmp1); 458 mr_free(tmp1); 459 460 log_msg(3, "proto = %s", bkpinfo->netfs_proto); 461 log_msg(3, "mount = %s", bkpinfo->netfs_mount); 462 if (bkpinfo->netfs_user) { 463 log_msg(3, "user = %s", bkpinfo->netfs_user); 464 } 465 log_msg(3, "isodir= %s", bkpinfo->isodir); 466 467 if (strlen(bkpinfo->isodir) < 3) { 468 log_to_screen("Network share %s is not mounted. Trying to mount it for you.\n",bkpinfo->netfs_mount); 469 if (bkpinfo->netfs_user) { 470 if (strstr(bkpinfo->netfs_proto, "sshfs")) { 471 mr_asprintf(tmp1, "sshfs %s@%s", bkpinfo->netfs_user, bkpinfo->netfs_mount); 472 } else if (strstr(bkpinfo->netfs_proto, "smbfs")) { 473 mr_asprintf(tmp1, "mount -t cifs %s -o user=%s", bkpinfo->netfs_mount, bkpinfo->netfs_user); 474 } else if (strstr(bkpinfo->netfs_proto, "nfs")) { 475 mr_asprintf(tmp1, "mount -t %s %s@%s", bkpinfo->netfs_proto, bkpinfo->netfs_user, bkpinfo->netfs_mount); 476 } else { 477 log_to_screen("Protocol %s not supported yet for network backups.\n", bkpinfo->netfs_proto); 478 fatal_error("Bad Protocol\n"); 479 } 480 } else { 481 if (strstr(bkpinfo->netfs_proto, "sshfs")) { 482 mr_asprintf(tmp1, "sshfs %s", bkpinfo->netfs_mount); 483 } else if (strstr(bkpinfo->netfs_proto, "smbfs")) { 484 mr_asprintf(tmp1, "mount -t cifs %s", bkpinfo->netfs_mount); 485 } else if (strstr(bkpinfo->netfs_proto, "nfs")) { 486 mr_asprintf(tmp1, "mount -t %s %s", bkpinfo->netfs_proto, bkpinfo->netfs_mount); 487 } else { 488 log_to_screen("Protocol %s not supported yet for network backups.\n", bkpinfo->netfs_proto); 489 fatal_error("Bad Protocol\n"); 490 } 491 } 492 i = system(tmp1); 493 mr_free(tmp1); 494 495 if (i) { 496 log_to_screen("Unable to mount Network share %s. Please mount manually.\n", bkpinfo->netfs_mount); 497 retval++; 498 } else { 499 if (bkpinfo->netfs_user) { 500 mr_asprintf(tmp1, "mount | grep -E \"^[%s@]*%s[/]* .*\" | cut -d' ' -f3", bkpinfo->netfs_user, bkpinfo->netfs_mount); 501 } else { 502 mr_asprintf(tmp1, "mount | grep -E \"^%s[/]* .*\" | cut -d' ' -f3", bkpinfo->netfs_mount); 503 } 504 mr_free(bkpinfo->isodir); 505 bkpinfo->isodir = call_program_and_get_last_line_of_output(tmp1); 506 if (strlen(bkpinfo->isodir) < 3) { 507 retval++; 508 log_to_screen("Network share %s is strangely not mounted. Please mount manually...\n", bkpinfo->netfs_mount); 509 } 510 } 511 } 512 } 513 514 if (flag_set['c']) { 515 bkpinfo->backup_media_type = cdr; 516 } 517 if (flag_set['C']) { 518 bkpinfo->backup_media_type = cdstream; 519 } 520 if (flag_set['i']) { 521 bkpinfo->backup_media_type = iso; 522 } 523 if (flag_set['n']) { 524 bkpinfo->backup_media_type = netfs; 525 /* Never try to eject a Network device */ 526 bkpinfo->please_dont_eject = TRUE; 527 } 528 if (flag_set['r']) { 529 bkpinfo->backup_media_type = dvd; 530 } 531 if (flag_set['t']) { 532 bkpinfo->backup_media_type = tape; 533 } 534 if (flag_set['u']) { 535 bkpinfo->backup_media_type = udev; 536 } 537 if (flag_set['U']) { 538 bkpinfo->backup_media_type = usb; 539 /* Never try to eject a USB device */ 540 bkpinfo->please_dont_eject = TRUE; 541 } 542 if (flag_set['z']) { 543 if ((tmp = find_home_of_exe("getfattr")) != NULL) { 544 mr_asprintf(g_getfattr,"getfattr"); 545 } 546 mr_free(tmp); 547 if ((tmp = find_home_of_exe("getfacl")) != NULL) { 548 mr_asprintf(g_getfattr,"getfaacl"); 549 } 550 mr_free(tmp); 551 } 552 553 /* optional, popular */ 554 if (flag_set['g']) { 555 g_text_mode = FALSE; 556 } 557 558 if (flag_set['E']) { 559 if ((flag_val['E'][0] == '-')) { 560 retval++; 561 log_to_screen("Please supply a sensible value with '-E'\n"); 562 } 563 mr_asprintf(tmp1, "%s", flag_val['E']); 564 565 p = tmp1; 566 q = tmp1; 567 568 /* Cut the flag_val['E'] in parts containing all paths to test them */ 569 while (p != NULL) { 570 q = strchr(p, '|'); 571 if (q != NULL) { 572 *q = '\0'; 573 /* Fix bug 14 where ending / cause a problem later 574 * so handled here for the moment */ 575 q--; 576 if (*q == '/') { 577 *q = '\0'; 578 } 579 q++; 580 /* End of bug fix */ 581 if ((stat(p, &buf) != 0) && (! bkpinfo->restore_data)) { 582 log_msg(1, "WARNING ! %s doesn't exist", p); 583 } 584 p = q+1 ; 585 } else { 586 if ((stat(p, &buf) != 0) && (! bkpinfo->restore_data)) { 587 log_msg(1, "WARNING ! %s doesn't exist", p); 588 } 589 p = NULL; 590 } 591 } 592 mr_free(tmp1); 593 594 mr_make_devlist_from_pathlist(flag_val['E'], 'E'); 595 log_msg(4, "Finished with the -E option"); 596 } 597 598 if (flag_set['e']) { 599 bkpinfo->please_dont_eject = TRUE; 600 } 601 602 if (flag_set['M']) { 603 g_max_biggie_size = atol(flag_val['M']); 604 log_msg(1, "Max size for biggie file is now %ld KB", g_max_biggie_size); 605 } 606 607 if ((flag_set['N']) && (! bkpinfo->restore_data)) // exclude Network mounts & devices 608 { 609 psz = list_of_NETFS_mounts_only(); 610 log_msg(5, "-N means we'll exclude %s", psz); 611 if (bkpinfo->exclude_paths) { 612 mr_strcat(bkpinfo->exclude_paths, "|%s", psz); 613 mr_free(psz); 614 } else { 615 bkpinfo->exclude_paths = psz; 616 } 617 618 if (bkpinfo->exclude_paths != NULL) { 619 log_msg(3, "-N means we're now excluding %s", bkpinfo->exclude_paths); 620 } 621 } 622 623 if (flag_set['b']) { 624 mr_asprintf(psz, "%s", flag_val['b']); 625 log_msg(1, "psz = '%s'", psz); 626 if (psz[strlen(psz) - 1] == 'k') { 627 psz[strlen(psz) - 1] = '\0'; 628 itbs = atol(psz) * 1024L; 629 } else { 630 itbs = atol(psz); 631 } 632 mr_free(psz); 633 log_msg(1, "'%s' --> %ld", flag_val['b'], itbs); 634 log_msg(1, "Internal tape block size is now %ld bytes", itbs); 635 if (itbs % 512 != 0 || itbs < 256 || itbs > 1024L * 1024) { 636 fatal_error("Are you nuts? Silly, your internal tape block size is. Abort, I shall."); 637 } 638 bkpinfo->internal_tape_block_size = itbs; 639 } 640 641 if ((flag_set['D']) && (! bkpinfo->restore_data)) { 642 bkpinfo->differential = 1; 643 // bkpinfo->differential = atoi (flag_val['D']); 644 if ((bkpinfo->differential < 1) || (bkpinfo->differential > 9)) { 645 fatal_error("The D option should be between 1 and 9 inclusive"); 646 } 647 } 648 649 if (flag_set['x']) { 650 mr_asprintf(bkpinfo->image_devs, "%s", flag_val['x']); 651 if ((run_program_and_log_output("which ntfsclone", 2)) && (! bkpinfo->restore_data)) { 652 fatal_error("Please install ntfsprogs package/tarball."); 653 } 654 } 655 656 if (flag_set['m']) { 657 bkpinfo->manual_cd_tray = TRUE; 658 } 659 660 if ((flag_set['k']) && (! bkpinfo->restore_data)) { 661 mr_asprintf(bkpinfo->kernel_path, "%s", flag_val['k']); 662 if (!does_file_exist(bkpinfo->kernel_path)) { 663 retval++; 664 log_to_screen("You specified kernel '%s', which does not exist\n", bkpinfo->kernel_path); 665 } 666 } 667 668 if (flag_set['p']) { 669 mr_asprintf(bkpinfo->prefix, "%s", flag_val['p']); 670 log_msg(1,"Prefix forced to %s",bkpinfo->prefix); 671 } 672 673 if (flag_set['d']) { /* backup directory (if ISO/NETFS) */ 674 if (flag_set['i']) { 675 // what is flag_val['d'] is NULL/undefined 676 mr_asprintf(bkpinfo->isodir, "%s", flag_val['d']); 677 mr_asprintf(tmp1, "ls -l %s", bkpinfo->isodir); 678 if (run_program_and_log_output(tmp1, 2)) { 679 mr_free(tmp1); 680 fatal_error("output folder does not exist - please create it"); 681 } 682 mr_free(tmp1); 683 } else if (flag_set['n']) { 684 mr_free(bkpinfo->netfs_remote_dir); 685 // what is flag_val['d'] is NULL/undefined 686 mr_asprintf(bkpinfo->netfs_remote_dir, "%s", flag_val['d']); 687 } else { /* backup device (if tape/CD-R/CD-RW) */ 688 /* bkpinfo-> media_device already setup upper */ 689 } 690 } 691 692 if ((flag_set['n']) && (! bkpinfo->restore_data)) { 693 mr_asprintf(tmp1,"%s/%s/.dummy.txt", bkpinfo->isodir,bkpinfo->netfs_remote_dir); 694 if ((bkpinfo->netfs_user) && (strstr(bkpinfo->netfs_proto,"nfs"))) { 695 mr_asprintf(tmp2, "su - %s -c \"echo hi > %s\"", bkpinfo->netfs_user, tmp1); 696 } else { 697 mr_asprintf(tmp2, "echo hi > %s", tmp1); 698 } 699 i = run_program_and_log_output(tmp2, 2); 700 mr_free(tmp2); 701 702 if (i) { 703 retval++; 704 log_to_screen("Are you sure directory '%s' exists in remote dir '%s'?\nIf so, do you have rights to write to it?\n", bkpinfo->netfs_remote_dir, bkpinfo->netfs_mount); 705 } 706 unlink(tmp1); 707 mr_free(tmp1); 708 } 709 710 if (!flag_set['d'] && (flag_set['c'] || flag_set['w'] || flag_set['C'])) { 711 tmp1 = mr_popup_and_get_string("Device", "Please specify the device", bkpinfo->media_device); 712 if (tmp1 == NULL) { 713 retval++; 714 log_to_screen("User opted to cancel."); 715 } else { 716 mr_free(bkpinfo->media_device); 717 bkpinfo->media_device = tmp1; 718 } 719 } else { 720 } 721 722 if ((!flag_set['d'] && !flag_set['n'] && !flag_set['C']) && (! bkpinfo->restore_data)) { 723 retval++; 724 log_to_screen("Please specify the backup device/directory.\n"); 725 fatal_error("You didn't use -d to specify the backup device/directory."); 726 } 727 728 for (i = '0'; i <= '9'; i++) { 729 if (flag_set[i]) { 730 bkpinfo->compression_level = i - '0'; 731 } /* not '\0' but '0' */ 732 } 733 734 if (flag_set['S']) { 735 setup_scratchdir(flag_val['S']); 736 mr_asprintf(tmp1, "touch %s/.foo.dat", bkpinfo->scratchdir); 737 if (run_program_and_log_output(tmp1, 1)) { 738 retval++; 739 mr_free(tmp1); 740 log_to_screen("Please specify a scratchdir which I can write to. :)"); 741 fatal_error("I cannot write to the scratchdir you specified."); 742 } 743 mr_free(tmp1); 744 745 mr_asprintf(tmp1, "ln -sf %s/.foo.dat %s/.bar.dat", bkpinfo->scratchdir, bkpinfo->scratchdir); 746 if (run_program_and_log_output(tmp1, 1)) { 747 retval++; 748 mr_free(tmp1); 749 log_to_screen("Please don't specify a SAMBA or VFAT or NFS scratchdir."); 750 fatal_error("I cannot write to the scratchdir you specified."); 751 } 752 mr_free(tmp1); 753 } 754 755 if (flag_set['T']) { 756 setup_tmpdir(flag_val['T']); 757 mr_asprintf(tmp1, "touch %s/.foo.dat", bkpinfo->tmpdir); 758 i = run_program_and_log_output(tmp1, 1); 759 mr_free(tmp1); 760 761 if (i) { 762 retval++; 763 log_to_screen("Please specify a tempdir which I can write to. :)"); 764 fatal_error("I cannot write to the tempdir you specified."); 765 } 766 mr_asprintf(tmp1, "ln -sf %s/.foo.dat %s/.bar.dat", bkpinfo->tmpdir, bkpinfo->tmpdir); 767 i = run_program_and_log_output(tmp1, 1); 768 mr_free(tmp1); 769 770 if (i) { 771 retval++; 772 log_to_screen("Please don't specify a SAMBA or VFAT or NFS tmpdir."); 773 fatal_error("I cannot write to the tempdir you specified."); 774 } 775 } 776 777 if ((flag_set['A']) && (! bkpinfo->restore_data)) { 778 mr_asprintf(bkpinfo->call_after_iso, "%s", flag_val['A']); 779 } 780 781 if ((flag_set['B']) && (! bkpinfo->restore_data)) { 782 mr_asprintf(bkpinfo->call_before_iso, "%s", flag_val['B']); 783 } 784 785 if ((flag_set['H']) && (! bkpinfo->restore_data)) { 786 g_cd_recovery = TRUE; 787 } 788 789 if ((flag_set['l']) && (! bkpinfo->restore_data)) { 790 #ifdef __FreeBSD__ 791 # define BOOT_LOADER_CHARS "GLBMR" 792 #else 793 # ifdef __IA64__ 794 # define BOOT_LOADER_CHARS "GER" 795 # else 796 # define BOOT_LOADER_CHARS "GLR" 797 # endif 798 #endif 799 if (!strchr(BOOT_LOADER_CHARS, (bkpinfo->boot_loader = flag_val['l'][0]))) { 800 log_msg(1, "%c? What is %c? I need G, L, E or R.", bkpinfo->boot_loader, bkpinfo->boot_loader); 801 fatal_error("Please specify GRUB, LILO, ELILO or RAW with the -l switch"); 802 } 803 #undef BOOT_LOADER_CHARS 804 } 805 806 if (flag_set['f']) { 807 mr_free(bkpinfo->boot_device); 808 mr_asprintf(bkpinfo->boot_device, "%s", resolve_softlinks_to_get_to_actual_device_file(flag_val['f'])); 809 } 810 811 if ((flag_set['P']) && (! bkpinfo->restore_data)) { 812 mr_asprintf(bkpinfo->postnuke_tarball, "%s", flag_val['P']); 813 } 814 815 if (flag_set['Q']) { 816 i = which_boot_loader(tmp); 817 log_msg(3, "boot loader is %c, residing at %s", i, tmp); 818 printf("boot loader is %c, residing at %s\n", i, tmp); 819 finish(0); 820 } 821 822 if ((flag_set['L']) && (! bkpinfo->restore_data)) { 823 bkpinfo->use_lzo = TRUE; 824 if (run_program_and_log_output("which lzop", 2)) { 825 retval++; 826 log_to_screen("Please install LZOP. You can't use '-L' until you do.\n"); 827 } 828 } 829 830 if (flag_set['F']) { 831 log_msg(3, "-F means we will fail immediately at the first interaction request"); 832 g_fail_immediately = TRUE; 833 } 834 835 if ((flag_set['G']) && (! bkpinfo->restore_data)) { 836 bkpinfo->use_gzip = TRUE; 837 if (run_program_and_log_output("which gzip", 2)) { 838 retval++; 839 log_to_screen("Please install gzip. You can't use '-G' until you do.\n"); 840 } 841 } 842 843 if ((flag_set['Y']) && (! bkpinfo->restore_data)) { 844 bkpinfo->use_lzma = TRUE; 845 if (run_program_and_log_output("which lzma", 2)) { 846 retval++; 847 log_to_screen("Please install lzma. You can't use '-Y' until you do.\n"); 848 } 849 } 850 851 bkpinfo->use_obdr = FALSE; 852 if (flag_set['o']) { 853 if ((!flag_set['t']) && (! bkpinfo->restore_data)) { 854 log_to_screen("OBDR support is only available for tapes. Use the -t option"); 855 fatal_error("Aborting"); 856 } 857 bkpinfo->use_obdr = TRUE; 858 } 859 860 #ifndef __FreeBSD__ 861 if ((!is_this_a_valid_disk_format("vfat")) && (! bkpinfo->restore_data)) { 862 bkpinfo->make_cd_use_lilo = TRUE; 863 log_to_screen("Your kernel appears not to support vfat filesystems. I am therefore"); 864 log_to_screen("using LILO instead of SYSLINUX as the media boot loader."); 865 } 866 if ((run_program_and_log_output("which mkfs.vfat", 2)) && (! bkpinfo->restore_data)) { 867 bkpinfo->make_cd_use_lilo = TRUE; 868 #ifdef __IA32__ 869 log_to_screen("Your filesystem is missing 'mkfs.vfat', so I cannot use SYSLINUX as"); 870 log_to_screen("your boot loader. I shall therefore use LILO instead."); 871 #endif 872 #ifdef __IA64__ 873 log_to_screen("Your filesystem is missing 'mkfs.vfat', so I cannot prepare the EFI"); 874 log_to_screen("environment correctly. Please install it."); 875 fatal_error("Aborting"); 876 #endif 877 } 878 #ifdef __IA64__ 879 /* We force ELILO usage on IA64 */ 880 bkpinfo->make_cd_use_lilo = TRUE; 881 #endif 882 #endif 883 884 if (! bkpinfo->restore_data) { 885 i = flag_set['O'] + flag_set['V']; 886 if (i == 0) { 887 retval++; 888 log_to_screen("Specify backup (-O), verify (-V) or both (-OV).\n"); 889 } 890 } 891 892 if ((! bkpinfo->restore_data) && (flag_set['Z'])) { 893 fatal_error("The -Z switch is only valid in restore mode"); 894 } 895 896 if (flag_set['Z']) { 897 if (! strcmp(flag_val['Z'], "nuke")) { 898 bkpinfo->restore_mode = nuke; 899 } else if (! strcmp(flag_val['Z'], "interactive")) { 900 bkpinfo->restore_mode = interactive; 901 } else if (! strcmp(flag_val['Z'], "compare")) { 902 bkpinfo->restore_mode = compare; 903 } else if (! strcmp(flag_val['Z'], "mbr")) { 904 bkpinfo->restore_mode = mbr; 905 } else if (! strcmp(flag_val['Z'], "iso")) { 906 bkpinfo->restore_mode = isoonly; 907 } else if (! strcmp(flag_val['Z'], "isonuke")) { 908 bkpinfo->restore_mode = isonuke; 909 } else { 910 bkpinfo->restore_mode = interactive; 911 } 912 } 913 914 /* and finally... */ 915 916 paranoid_free(tmp); 917 return (retval); 97 log_msg(1, "Type 'man mondoarchive' for more information"); 98 exit(1); 918 99 } 919 920 100 921 101 … … 983 163 984 164 985 986 987 165 /** 988 * Print a not-so-helpful help message and exit. 166 * Process mondoarchive's command-line switches. 167 * @param bkpinfo The backup information structure to populate. 168 * @param flag_val An array of the argument passed to each switch (the letter is the index). 169 * If a switch is not set or has no argument, the field in @p flag_val doesn't matter. 170 * @param flag_set An array of <tt>bool</tt>s indexed by switch letter: TRUE if it's set, 171 * FALSE if it's not. 172 * @return The number of problems with the switches, or 0 for success. 173 * @bug Maybe include a list of all switches (inc. intentionally undocumented ones not in the manual!) here? 989 174 */ 990 void help_screen() 175 int 176 process_switches(char flag_val[128][MAX_STR_LEN], bool flag_set[128]) 991 177 { 992 log_msg(1, "Type 'man mondoarchive' for more information"); 993 exit(1); 178 179 /*@ ints *** */ 180 int i = 0; 181 int retval = 0; 182 183 /*@ buffers ** */ 184 char *tmp = NULL; 185 char *tmp1 = NULL; 186 char *tmp2 = NULL; 187 char *psz = NULL; 188 char *p = NULL; 189 char *q = NULL; 190 char *q2 = NULL; 191 192 long itbs = 0L; 193 194 struct stat buf; 195 196 malloc_string(tmp); 197 198 assert(bkpinfo != NULL); 199 assert(flag_val != NULL); 200 assert(flag_set != NULL); 201 202 bkpinfo->internal_tape_block_size = DEFAULT_INTERNAL_TAPE_BLOCK_SIZE; 203 204 /* compulsory */ 205 i = flag_set['c'] + flag_set['i'] + flag_set['n'] + 206 flag_set['t'] + flag_set['u'] + flag_set['r'] + 207 flag_set['w'] + flag_set['C'] + flag_set['U']; 208 if ((i == 0) && (! bkpinfo->restore_data)) { 209 retval++; 210 log_to_screen("You must specify the media type\n"); 211 } 212 if (i > 1) { 213 retval++; 214 log_to_screen("Please specify only one media type\n"); 215 } 216 217 if (flag_set['K']) { 218 g_loglevel = atoi(flag_val['K']); 219 log_msg(1,"Loglevel forced to %d",g_loglevel); 220 if (g_loglevel < 3) { 221 g_loglevel = 3; 222 } 223 } 224 225 if ((flag_set['L'] && flag_set['0']) && (! bkpinfo->restore_data)) { 226 retval++; 227 log_to_screen("You cannot have 'no compression' _and_ LZOP.\n"); 228 } 229 if (! bkpinfo->restore_data) { 230 bkpinfo->backup_data = flag_set['O']; 231 } 232 bkpinfo->verify_data = flag_set['V']; 233 234 if (flag_set['I'] && !bkpinfo->backup_data) { 235 log_to_screen("-I switch is ignored if just verifying"); 236 } 237 if (flag_set['E'] && !bkpinfo->backup_data) { 238 log_to_screen("-E switch is ignored if just verifying"); 239 } 240 241 if ((tmp = find_home_of_exe("afio")) == NULL) { 242 mr_free(tmp); 243 if ((tmp = find_home_of_exe("star")) != NULL) { 244 mr_free(tmp); 245 flag_set['R'] = TRUE; 246 log_msg(1, "Using star instead of afio"); 247 } else { 248 mr_free(tmp); 249 fatal_error("Neither afio nor star is installed. Please install at least one."); 250 } 251 } 252 253 if (flag_set['R']) { 254 bkpinfo->use_star = TRUE; 255 if (flag_set['L']) { 256 fatal_error("You may not use star and lzop at the same time."); 257 } 258 if ((tmp = find_home_of_exe("star")) == NULL) { 259 mr_free(tmp); 260 fatal_error("Please install 'star' if you are going to use -R. Thanks."); 261 } 262 mr_free(tmp); 263 } 264 265 if ((flag_set['W']) && (! bkpinfo->restore_data)) { 266 bkpinfo->nonbootable_backup = TRUE; 267 log_to_screen("Warning - you have opted for non-bootable backup"); 268 if (flag_set['f'] || flag_set['l']) { 269 log_to_screen 270 ("You don't need to specify bootloader or bootdevice"); 271 } 272 } 273 274 if (flag_set['I']) { 275 if (flag_val['I'][0] == '-') { 276 retval++; 277 log_to_screen("Please supply a sensible value with '-I'\n"); 278 } 279 if (!strcmp(flag_val['I'],"/")) { 280 log_msg(2, "'/' is pleonastic."); 281 } 282 if (bkpinfo->include_paths && bkpinfo->include_paths[0]) { 283 mr_strcat(bkpinfo->include_paths, "|"); 284 } 285 286 mr_asprintf(tmp1, "%s", flag_val['I']); 287 p = tmp1; 288 q = tmp1; 289 290 /* Cut the flag_val['I'] in parts containing all paths to test them */ 291 while (p != NULL) { 292 q = strchr(p, '|'); 293 if (q != NULL) { 294 *q = '\0'; 295 if ((stat(p, &buf) != 0) && (! bkpinfo->restore_data)) { 296 log_msg(1, "ERROR ! %s doesn't exist", p); 297 fatal_error("ERROR ! You specified a directory to include which doesn't exist"); 298 } 299 p = q+1 ; 300 } else { 301 if ((stat(p, &buf) != 0) && (! bkpinfo->restore_data)) { 302 log_msg(1, "ERROR ! %s doesn't exist", p); 303 fatal_error("ERROR ! You specified a directory to include which doesn't exist"); 304 } 305 p = NULL; 306 } 307 } 308 mr_free(tmp1); 309 mr_make_devlist_from_pathlist(flag_val['I'], 'I'); 310 log_msg(4, "Finished with the -I option"); 311 } 312 313 if (g_kernel_version >= 2.6 && !flag_set['d'] && (flag_set['c'] || flag_set['w']) && (! bkpinfo->restore_data)) { 314 fatal_error("If you are using the 2.6.x kernel, please specify the CD-R(W) device."); 315 } 316 317 318 if (flag_set['J']) { 319 if (flag_set['I']) { 320 retval++; 321 log_to_screen("Please do not use -J in combination with -I. If you want to make a list of files to backup, that's fine, use -J <filename> but please don't muddy the waters by combining -J with -I. Thanks. :-)"); 322 } 323 bkpinfo->make_filelist = FALSE; 324 mr_asprintf(bkpinfo->include_paths, "%s", flag_val['J']); 325 } 326 327 if ((flag_set['c'] || flag_set['w'] || flag_set['C'] || flag_set['r']) && (! bkpinfo->restore_data)) { 328 if (system("which cdrecord > /dev/null 2> /dev/null") && system("which dvdrecord > /dev/null 2> /dev/null")) { 329 fatal_error("Please install dvdrecord/cdrecord and try again."); 330 } 331 if (flag_set['C']) { 332 bkpinfo->cdrw_speed = atoi(flag_val['C']); 333 if (bkpinfo->cdrw_speed < 1) { 334 fatal_error("You specified a silly speed for a CD-R[W] drive"); 335 } 336 if (!flag_set['L']) { 337 log_to_screen("You must use -L with -C. Therefore I am setting it for you."); 338 flag_set['L'] = 1; 339 flag_val['L'][0] = '\0'; 340 } 341 } else { 342 log_msg(3, "flag_val['c'] = %s", flag_val['c']); 343 log_msg(3, "flag_val['w'] = %s", flag_val['w']); 344 if (flag_set['c']) { 345 bkpinfo->cdrw_speed = atoi(flag_val['c']); 346 } else if (flag_set['w']) { 347 bkpinfo->cdrw_speed = atoi(flag_val['w']); 348 } else if (flag_set['r']) { 349 bkpinfo->cdrw_speed = 1; /*atoi(flag_val['r']); */ 350 } 351 352 if (bkpinfo->cdrw_speed < 1) { 353 fatal_error("You specified a silly speed for a CD-R[W] drive"); 354 } 355 } 356 } 357 358 if ((flag_set['t'] && !flag_set['d']) && (! bkpinfo->restore_data)) { 359 log_it("Hmm! No tape drive specified. Let's see what we can do."); 360 if ((bkpinfo->media_device = find_tape_device()) == NULL) { 361 fatal_error("Tape device not specified and I couldn't find it either. Please use option -d"); 362 } 363 flag_set['d'] = TRUE; 364 log_to_screen("You didn't specify a tape streamer device. I'm assuming %s", bkpinfo->media_device); 365 } 366 367 if (flag_set['U']) // USB 368 { 369 if (! flag_set['d']) { 370 fatal_error("You need to specify a device file with -d for bootable USB device usage"); 371 } 372 if ((!flag_set['s']) && (! bkpinfo->restore_data)) { 373 fatal_error("You did not specify a size (-s) for your USB device. Aborting"); 374 } 375 } 376 377 if (flag_set['r']) // DVD 378 { 379 if (flag_set['m']) { 380 fatal_error("Manual CD tray (-m) not yet supported in conjunction w/ DVD drives. Drop -m."); 381 } 382 if (!flag_set['d']) { 383 if ((bkpinfo->media_device = find_optical_device()) != NULL) { 384 flag_set['d'] = TRUE; 385 log_to_screen("I guess DVD drive is at %s", bkpinfo->media_device); 386 } 387 } 388 if (strchr(bkpinfo->media_device, ',')) { 389 fatal_error("Please don't give a SCSI node. Give a _device_, preferably a /dev entry, for the parameter of the -d flag."); 390 } 391 if (! bkpinfo->restore_data) { 392 if (!flag_set['s']) { 393 sprintf(flag_val['s'], "%d", DEFAULT_DVD_DISK_SIZE); // 4.7 salesman's GB = 4.482 real GB = 4582 MB 394 strcat(flag_val['s'], "m"); 395 log_to_screen("You did not specify a size (-s) for DVD. I'm guessing %s.", flag_val['s']); 396 flag_set['s'] = 1; 397 } 398 } 399 } 400 401 if (flag_set['t'] || flag_set['u']) { /* tape size */ 402 if (strchr(flag_val['d'], ',')) { 403 fatal_error("Please don't give a SCSI node. Give a _device_, preferably a /dev entry, for the parameter of the -d flag."); 404 } 405 if ((flag_set['O']) && (! bkpinfo->restore_data)) { 406 if (flag_set['s']) { 407 if (flag_set['t']) { 408 fatal_error("For the moment, please don't specify a tape size. Mondo should handle end-of-tape gracefully anyway."); 409 } 410 if (process_the_s_switch(flag_val['s'])) { 411 fatal_error("Bad -s switch"); 412 } 413 } else if (flag_set['u'] || flag_set['t']) { 414 bkpinfo->media_size = 0; 415 } else { 416 retval++; 417 log_to_screen("Tape size not specified.\n"); 418 } 419 } 420 } else if (! bkpinfo->restore_data) { /* CD|USB size */ 421 if (flag_set['s']) { 422 if (process_the_s_switch(flag_val['s'])) { 423 fatal_error("Bad -s switch"); 424 } 425 } 426 if (flag_set['w']) { 427 bkpinfo->wipe_media_first = TRUE; 428 } /* CD-RW */ 429 } 430 431 if (flag_set['n']) { 432 mr_asprintf(bkpinfo->netfs_mount, "%s", flag_val['n']); 433 if (!flag_set['d']) { 434 mr_asprintf(bkpinfo->netfs_remote_dir, "/"); 435 mr_asprintf(bkpinfo->isodir, "%s", "."); 436 } 437 /* test for protocol */ 438 p = strstr(bkpinfo->netfs_mount, "://"); 439 if (p == NULL) { 440 /* protocol not found assuming NFS for compatibility */ 441 mr_asprintf(q,"nfs"); 442 443 p = strchr(bkpinfo->netfs_mount, ':'); 444 if (p == NULL) { 445 fatal_error("No protocol specified for remote share mount, nor any old NFS syntax found.\nPlease do man mondoarchive as syntax changed"); 446 } 447 /* p points on to the string server:/path */ 448 p = bkpinfo->netfs_mount; 449 450 } else { 451 /* Isolate the protocol */ 452 *p = '\0'; 453 mr_asprintf(q,"%s",bkpinfo->netfs_mount); 454 455 /* Skip proto now */ 456 p++; 457 p++; 458 p++; 459 } 460 /* whatever done before proto is pointed to by q */ 461 bkpinfo->netfs_proto = q; 462 463 /* p points on to the string server:/path */ 464 /* Store the 2 values */ 465 q2 = bkpinfo->netfs_mount; 466 mr_asprintf(bkpinfo->netfs_mount, "%s", p); 467 mr_free(q2); 468 469 /* test if we specified a user */ 470 p = strchr(bkpinfo->netfs_mount, '@'); 471 if (p != NULL) { 472 /* User found. Store the 2 values */ 473 mr_asprintf(bkpinfo->netfs_user, "%s", bkpinfo->netfs_mount); 474 p = strchr(bkpinfo->netfs_user, '@'); 475 *p = '\0'; 476 p = strchr(bkpinfo->netfs_mount, '@'); 477 p++; 478 /* new netfs mount */ 479 q2 = bkpinfo->netfs_mount; 480 mr_asprintf(bkpinfo->netfs_mount, "%s", p); 481 mr_free(q2); 482 } 483 if (bkpinfo->netfs_user != NULL) { 484 mr_asprintf(tmp1, "mount | grep -E \"^[a-z]*#*[%s@]*%s[/]* .*\" | cut -d' ' -f3", bkpinfo->netfs_user, bkpinfo->netfs_mount); 485 } else { 486 mr_asprintf(tmp1, "mount | grep -E \"^[a-z]*#*%s[/]* .*\" | cut -d' ' -f3", bkpinfo->netfs_mount); 487 } 488 mr_free(bkpinfo->isodir); 489 bkpinfo->isodir = call_program_and_get_last_line_of_output(tmp1); 490 mr_free(tmp1); 491 492 log_msg(3, "proto = %s", bkpinfo->netfs_proto); 493 log_msg(3, "mount = %s", bkpinfo->netfs_mount); 494 if (bkpinfo->netfs_user) { 495 log_msg(3, "user = %s", bkpinfo->netfs_user); 496 } 497 log_msg(3, "isodir= %s", bkpinfo->isodir); 498 499 if (strlen(bkpinfo->isodir) < 3) { 500 log_to_screen("Network share %s is not mounted. Trying to mount it for you.\n",bkpinfo->netfs_mount); 501 if (bkpinfo->netfs_user) { 502 if (strstr(bkpinfo->netfs_proto, "sshfs")) { 503 mr_asprintf(tmp1, "sshfs %s@%s", bkpinfo->netfs_user, bkpinfo->netfs_mount); 504 } else if (strstr(bkpinfo->netfs_proto, "smbfs")) { 505 mr_asprintf(tmp1, "mount -t cifs %s -o user=%s", bkpinfo->netfs_mount, bkpinfo->netfs_user); 506 } else if (strstr(bkpinfo->netfs_proto, "nfs")) { 507 mr_asprintf(tmp1, "mount -t %s %s@%s", bkpinfo->netfs_proto, bkpinfo->netfs_user, bkpinfo->netfs_mount); 508 } else { 509 log_to_screen("Protocol %s not supported yet for network backups.\n", bkpinfo->netfs_proto); 510 fatal_error("Bad Protocol\n"); 511 } 512 } else { 513 if (strstr(bkpinfo->netfs_proto, "sshfs")) { 514 mr_asprintf(tmp1, "sshfs %s", bkpinfo->netfs_mount); 515 } else if (strstr(bkpinfo->netfs_proto, "smbfs")) { 516 mr_asprintf(tmp1, "mount -t cifs %s", bkpinfo->netfs_mount); 517 } else if (strstr(bkpinfo->netfs_proto, "nfs")) { 518 mr_asprintf(tmp1, "mount -t %s %s", bkpinfo->netfs_proto, bkpinfo->netfs_mount); 519 } else { 520 log_to_screen("Protocol %s not supported yet for network backups.\n", bkpinfo->netfs_proto); 521 fatal_error("Bad Protocol\n"); 522 } 523 } 524 i = system(tmp1); 525 mr_free(tmp1); 526 527 if (i) { 528 log_to_screen("Unable to mount Network share %s. Please mount manually.\n", bkpinfo->netfs_mount); 529 retval++; 530 } else { 531 if (bkpinfo->netfs_user) { 532 mr_asprintf(tmp1, "mount | grep -E \"^[%s@]*%s[/]* .*\" | cut -d' ' -f3", bkpinfo->netfs_user, bkpinfo->netfs_mount); 533 } else { 534 mr_asprintf(tmp1, "mount | grep -E \"^%s[/]* .*\" | cut -d' ' -f3", bkpinfo->netfs_mount); 535 } 536 mr_free(bkpinfo->isodir); 537 bkpinfo->isodir = call_program_and_get_last_line_of_output(tmp1); 538 if (strlen(bkpinfo->isodir) < 3) { 539 retval++; 540 log_to_screen("Network share %s is strangely not mounted. Please mount manually...\n", bkpinfo->netfs_mount); 541 } 542 } 543 } 544 } 545 546 if (flag_set['c']) { 547 bkpinfo->backup_media_type = cdr; 548 } 549 if (flag_set['C']) { 550 bkpinfo->backup_media_type = cdstream; 551 } 552 if (flag_set['i']) { 553 bkpinfo->backup_media_type = iso; 554 } 555 if (flag_set['n']) { 556 bkpinfo->backup_media_type = netfs; 557 /* Never try to eject a Network device */ 558 bkpinfo->please_dont_eject = TRUE; 559 } 560 if (flag_set['r']) { 561 bkpinfo->backup_media_type = dvd; 562 } 563 if (flag_set['t']) { 564 bkpinfo->backup_media_type = tape; 565 } 566 if (flag_set['u']) { 567 bkpinfo->backup_media_type = udev; 568 } 569 if (flag_set['U']) { 570 bkpinfo->backup_media_type = usb; 571 /* Never try to eject a USB device */ 572 bkpinfo->please_dont_eject = TRUE; 573 } 574 if (flag_set['z']) { 575 if ((tmp = find_home_of_exe("getfattr")) != NULL) { 576 mr_asprintf(g_getfattr,"getfattr"); 577 } 578 mr_free(tmp); 579 if ((tmp = find_home_of_exe("getfacl")) != NULL) { 580 mr_asprintf(g_getfattr,"getfaacl"); 581 } 582 mr_free(tmp); 583 } 584 585 /* optional, popular */ 586 if (flag_set['g']) { 587 g_text_mode = FALSE; 588 } 589 590 if (flag_set['E']) { 591 if ((flag_val['E'][0] == '-')) { 592 retval++; 593 log_to_screen("Please supply a sensible value with '-E'\n"); 594 } 595 mr_asprintf(tmp1, "%s", flag_val['E']); 596 597 p = tmp1; 598 q = tmp1; 599 600 /* Cut the flag_val['E'] in parts containing all paths to test them */ 601 while (p != NULL) { 602 q = strchr(p, '|'); 603 if (q != NULL) { 604 *q = '\0'; 605 /* Fix bug 14 where ending / cause a problem later 606 * so handled here for the moment */ 607 q--; 608 if (*q == '/') { 609 *q = '\0'; 610 } 611 q++; 612 /* End of bug fix */ 613 if ((stat(p, &buf) != 0) && (! bkpinfo->restore_data)) { 614 log_msg(1, "WARNING ! %s doesn't exist", p); 615 } 616 p = q+1 ; 617 } else { 618 if ((stat(p, &buf) != 0) && (! bkpinfo->restore_data)) { 619 log_msg(1, "WARNING ! %s doesn't exist", p); 620 } 621 p = NULL; 622 } 623 } 624 mr_free(tmp1); 625 626 mr_make_devlist_from_pathlist(flag_val['E'], 'E'); 627 log_msg(4, "Finished with the -E option"); 628 } 629 630 if (flag_set['e']) { 631 bkpinfo->please_dont_eject = TRUE; 632 } 633 634 if (flag_set['M']) { 635 g_max_biggie_size = atol(flag_val['M']); 636 log_msg(1, "Max size for biggie file is now %ld KB", g_max_biggie_size); 637 } 638 639 if ((flag_set['N']) && (! bkpinfo->restore_data)) // exclude Network mounts & devices 640 { 641 psz = list_of_NETFS_mounts_only(); 642 log_msg(5, "-N means we'll exclude %s", psz); 643 if (bkpinfo->exclude_paths) { 644 mr_strcat(bkpinfo->exclude_paths, "|%s", psz); 645 mr_free(psz); 646 } else { 647 bkpinfo->exclude_paths = psz; 648 } 649 650 if (bkpinfo->exclude_paths != NULL) { 651 log_msg(3, "-N means we're now excluding %s", bkpinfo->exclude_paths); 652 } 653 } 654 655 if (flag_set['b']) { 656 mr_asprintf(psz, "%s", flag_val['b']); 657 log_msg(1, "psz = '%s'", psz); 658 if (psz[strlen(psz) - 1] == 'k') { 659 psz[strlen(psz) - 1] = '\0'; 660 itbs = atol(psz) * 1024L; 661 } else { 662 itbs = atol(psz); 663 } 664 mr_free(psz); 665 log_msg(1, "'%s' --> %ld", flag_val['b'], itbs); 666 log_msg(1, "Internal tape block size is now %ld bytes", itbs); 667 if (itbs % 512 != 0 || itbs < 256 || itbs > 1024L * 1024) { 668 fatal_error("Are you nuts? Silly, your internal tape block size is. Abort, I shall."); 669 } 670 bkpinfo->internal_tape_block_size = itbs; 671 } 672 673 if ((flag_set['D']) && (! bkpinfo->restore_data)) { 674 bkpinfo->differential = 1; 675 // bkpinfo->differential = atoi (flag_val['D']); 676 if ((bkpinfo->differential < 1) || (bkpinfo->differential > 9)) { 677 fatal_error("The D option should be between 1 and 9 inclusive"); 678 } 679 } 680 681 if (flag_set['x']) { 682 mr_asprintf(bkpinfo->image_devs, "%s", flag_val['x']); 683 if ((run_program_and_log_output("which ntfsclone", 2)) && (! bkpinfo->restore_data)) { 684 fatal_error("Please install ntfsprogs package/tarball."); 685 } 686 } 687 688 if (flag_set['m']) { 689 bkpinfo->manual_cd_tray = TRUE; 690 } 691 692 if ((flag_set['k']) && (! bkpinfo->restore_data)) { 693 mr_asprintf(bkpinfo->kernel_path, "%s", flag_val['k']); 694 if (!does_file_exist(bkpinfo->kernel_path)) { 695 retval++; 696 log_to_screen("You specified kernel '%s', which does not exist\n", bkpinfo->kernel_path); 697 } 698 } 699 700 if (flag_set['p']) { 701 mr_asprintf(bkpinfo->prefix, "%s", flag_val['p']); 702 log_msg(1,"Prefix forced to %s",bkpinfo->prefix); 703 } 704 705 if (flag_set['d']) { /* backup directory (if ISO/NETFS) */ 706 if (flag_set['i']) { 707 // what is flag_val['d'] is NULL/undefined 708 mr_asprintf(bkpinfo->isodir, "%s", flag_val['d']); 709 mr_asprintf(tmp1, "ls -l %s", bkpinfo->isodir); 710 if (run_program_and_log_output(tmp1, 2)) { 711 mr_free(tmp1); 712 fatal_error("output folder does not exist - please create it"); 713 } 714 mr_free(tmp1); 715 } else if (flag_set['n']) { 716 mr_free(bkpinfo->netfs_remote_dir); 717 // what is flag_val['d'] is NULL/undefined 718 mr_asprintf(bkpinfo->netfs_remote_dir, "%s", flag_val['d']); 719 } else { /* backup device (if tape/CD-R/CD-RW) */ 720 /* bkpinfo-> media_device already setup upper */ 721 } 722 } 723 724 if ((flag_set['n']) && (! bkpinfo->restore_data)) { 725 mr_asprintf(tmp1,"%s/%s/.dummy.txt", bkpinfo->isodir,bkpinfo->netfs_remote_dir); 726 if ((bkpinfo->netfs_user) && (strstr(bkpinfo->netfs_proto,"nfs"))) { 727 mr_asprintf(tmp2, "su - %s -c \"echo hi > %s\"", bkpinfo->netfs_user, tmp1); 728 } else { 729 mr_asprintf(tmp2, "echo hi > %s", tmp1); 730 } 731 i = run_program_and_log_output(tmp2, 2); 732 mr_free(tmp2); 733 734 if (i) { 735 retval++; 736 log_to_screen("Are you sure directory '%s' exists in remote dir '%s'?\nIf so, do you have rights to write to it?\n", bkpinfo->netfs_remote_dir, bkpinfo->netfs_mount); 737 } 738 unlink(tmp1); 739 mr_free(tmp1); 740 } 741 742 if (!flag_set['d'] && (flag_set['c'] || flag_set['w'] || flag_set['C'])) { 743 tmp1 = mr_popup_and_get_string("Device", "Please specify the device", bkpinfo->media_device); 744 if (tmp1 == NULL) { 745 retval++; 746 log_to_screen("User opted to cancel."); 747 } else { 748 mr_free(bkpinfo->media_device); 749 bkpinfo->media_device = tmp1; 750 } 751 } else { 752 } 753 754 if ((!flag_set['d'] && !flag_set['n'] && !flag_set['C']) && (! bkpinfo->restore_data)) { 755 retval++; 756 log_to_screen("Please specify the backup device/directory.\n"); 757 fatal_error("You didn't use -d to specify the backup device/directory."); 758 } 759 760 for (i = '0'; i <= '9'; i++) { 761 if (flag_set[i]) { 762 bkpinfo->compression_level = i - '0'; 763 } /* not '\0' but '0' */ 764 } 765 766 if (flag_set['S']) { 767 setup_scratchdir(flag_val['S']); 768 mr_asprintf(tmp1, "touch %s/.foo.dat", bkpinfo->scratchdir); 769 if (run_program_and_log_output(tmp1, 1)) { 770 retval++; 771 mr_free(tmp1); 772 log_to_screen("Please specify a scratchdir which I can write to. :)"); 773 fatal_error("I cannot write to the scratchdir you specified."); 774 } 775 mr_free(tmp1); 776 777 mr_asprintf(tmp1, "ln -sf %s/.foo.dat %s/.bar.dat", bkpinfo->scratchdir, bkpinfo->scratchdir); 778 if (run_program_and_log_output(tmp1, 1)) { 779 retval++; 780 mr_free(tmp1); 781 log_to_screen("Please don't specify a SAMBA or VFAT or NFS scratchdir."); 782 fatal_error("I cannot write to the scratchdir you specified."); 783 } 784 mr_free(tmp1); 785 } 786 787 if (flag_set['T']) { 788 setup_tmpdir(flag_val['T']); 789 mr_asprintf(tmp1, "touch %s/.foo.dat", bkpinfo->tmpdir); 790 i = run_program_and_log_output(tmp1, 1); 791 mr_free(tmp1); 792 793 if (i) { 794 retval++; 795 log_to_screen("Please specify a tempdir which I can write to. :)"); 796 fatal_error("I cannot write to the tempdir you specified."); 797 } 798 mr_asprintf(tmp1, "ln -sf %s/.foo.dat %s/.bar.dat", bkpinfo->tmpdir, bkpinfo->tmpdir); 799 i = run_program_and_log_output(tmp1, 1); 800 mr_free(tmp1); 801 802 if (i) { 803 retval++; 804 log_to_screen("Please don't specify a SAMBA or VFAT or NFS tmpdir."); 805 fatal_error("I cannot write to the tempdir you specified."); 806 } 807 } 808 809 if ((flag_set['A']) && (! bkpinfo->restore_data)) { 810 mr_asprintf(bkpinfo->call_after_iso, "%s", flag_val['A']); 811 } 812 813 if ((flag_set['B']) && (! bkpinfo->restore_data)) { 814 mr_asprintf(bkpinfo->call_before_iso, "%s", flag_val['B']); 815 } 816 817 if ((flag_set['H']) && (! bkpinfo->restore_data)) { 818 g_cd_recovery = TRUE; 819 } 820 821 if ((flag_set['l']) && (! bkpinfo->restore_data)) { 822 #ifdef __FreeBSD__ 823 # define BOOT_LOADER_CHARS "GLBMR" 824 #else 825 # ifdef __IA64__ 826 # define BOOT_LOADER_CHARS "GER" 827 # else 828 # define BOOT_LOADER_CHARS "GLR" 829 # endif 830 #endif 831 if (!strchr(BOOT_LOADER_CHARS, (bkpinfo->boot_loader = flag_val['l'][0]))) { 832 log_msg(1, "%c? What is %c? I need G, L, E or R.", bkpinfo->boot_loader, bkpinfo->boot_loader); 833 fatal_error("Please specify GRUB, LILO, ELILO or RAW with the -l switch"); 834 } 835 #undef BOOT_LOADER_CHARS 836 } 837 838 if (flag_set['f']) { 839 mr_free(bkpinfo->boot_device); 840 mr_asprintf(bkpinfo->boot_device, "%s", resolve_softlinks_to_get_to_actual_device_file(flag_val['f'])); 841 } 842 843 if ((flag_set['P']) && (! bkpinfo->restore_data)) { 844 mr_asprintf(bkpinfo->postnuke_tarball, "%s", flag_val['P']); 845 } 846 847 if (flag_set['Q']) { 848 i = which_boot_loader(tmp); 849 log_msg(3, "boot loader is %c, residing at %s", i, tmp); 850 printf("boot loader is %c, residing at %s\n", i, tmp); 851 finish(0); 852 } 853 854 if ((flag_set['L']) && (! bkpinfo->restore_data)) { 855 bkpinfo->use_lzo = TRUE; 856 if (run_program_and_log_output("which lzop", 2)) { 857 retval++; 858 log_to_screen("Please install LZOP. You can't use '-L' until you do.\n"); 859 } 860 } 861 862 if (flag_set['F']) { 863 log_msg(3, "-F means we will fail immediately at the first interaction request"); 864 g_fail_immediately = TRUE; 865 } 866 867 if ((flag_set['G']) && (! bkpinfo->restore_data)) { 868 bkpinfo->use_gzip = TRUE; 869 if (run_program_and_log_output("which gzip", 2)) { 870 retval++; 871 log_to_screen("Please install gzip. You can't use '-G' until you do.\n"); 872 } 873 } 874 875 if ((flag_set['Y']) && (! bkpinfo->restore_data)) { 876 bkpinfo->use_lzma = TRUE; 877 if (run_program_and_log_output("which lzma", 2)) { 878 retval++; 879 log_to_screen("Please install lzma. You can't use '-Y' until you do.\n"); 880 } 881 } 882 883 bkpinfo->use_obdr = FALSE; 884 if (flag_set['o']) { 885 if ((!flag_set['t']) && (! bkpinfo->restore_data)) { 886 log_to_screen("OBDR support is only available for tapes. Use the -t option"); 887 fatal_error("Aborting"); 888 } 889 bkpinfo->use_obdr = TRUE; 890 } 891 892 #ifndef __FreeBSD__ 893 if ((!is_this_a_valid_disk_format("vfat")) && (! bkpinfo->restore_data)) { 894 bkpinfo->make_cd_use_lilo = TRUE; 895 log_to_screen("Your kernel appears not to support vfat filesystems. I am therefore"); 896 log_to_screen("using LILO instead of SYSLINUX as the media boot loader."); 897 } 898 if ((run_program_and_log_output("which mkfs.vfat", 2)) && (! bkpinfo->restore_data)) { 899 bkpinfo->make_cd_use_lilo = TRUE; 900 #ifdef __IA32__ 901 log_to_screen("Your filesystem is missing 'mkfs.vfat', so I cannot use SYSLINUX as"); 902 log_to_screen("your boot loader. I shall therefore use LILO instead."); 903 #endif 904 #ifdef __IA64__ 905 log_to_screen("Your filesystem is missing 'mkfs.vfat', so I cannot prepare the EFI"); 906 log_to_screen("environment correctly. Please install it."); 907 fatal_error("Aborting"); 908 #endif 909 } 910 #ifdef __IA64__ 911 /* We force ELILO usage on IA64 */ 912 bkpinfo->make_cd_use_lilo = TRUE; 913 #endif 914 #endif 915 916 if (! bkpinfo->restore_data) { 917 i = flag_set['O'] + flag_set['V']; 918 if (i == 0) { 919 retval++; 920 log_to_screen("Specify backup (-O), verify (-V) or both (-OV).\n"); 921 } 922 } 923 924 if ((! bkpinfo->restore_data) && (flag_set['Z'])) { 925 fatal_error("The -Z switch is only valid in restore mode"); 926 } 927 928 if (flag_set['Z']) { 929 if (! strcmp(flag_val['Z'], "nuke")) { 930 bkpinfo->restore_mode = nuke; 931 } else if (! strcmp(flag_val['Z'], "interactive")) { 932 bkpinfo->restore_mode = interactive; 933 } else if (! strcmp(flag_val['Z'], "compare")) { 934 bkpinfo->restore_mode = compare; 935 } else if (! strcmp(flag_val['Z'], "mbr")) { 936 bkpinfo->restore_mode = mbr; 937 } else if (! strcmp(flag_val['Z'], "iso")) { 938 bkpinfo->restore_mode = isoonly; 939 } else if (! strcmp(flag_val['Z'], "isonuke")) { 940 bkpinfo->restore_mode = isonuke; 941 } else { 942 bkpinfo->restore_mode = interactive; 943 } 944 } 945 946 /* and finally... */ 947 948 paranoid_free(tmp); 949 return (retval); 950 } 951 952 953 954 /** 955 * @addtogroup cliGroup 956 * @{ 957 */ 958 /** 959 * Populate @p bkpinfo from the command-line parameters stored in @p argc and @p argv. 960 * @param argc The argument count, including the program name; @p argc passed to main(). 961 * @param argv The argument vector; @p argv passed to main(). 962 * @param bkpinfo The backup information structure to populate. 963 * @return The number of problems with the command line (0 for success). 964 */ 965 int 966 handle_incoming_parameters(int argc, char *argv[]) 967 { 968 /*@ int *** */ 969 int res = 0; 970 int retval = 0; 971 int i = 0; 972 973 /*@ buffers *************** */ 974 char flag_val[128][MAX_STR_LEN]; 975 bool flag_set[128]; 976 977 for (i = 0; i < 128; i++) { 978 flag_val[i][0] = '\0'; 979 flag_set[i] = FALSE; 980 } 981 bkpinfo->media_size = 650; /* default */ 982 res = retrieve_switches_from_command_line(argc, argv, flag_val, flag_set); 983 retval += res; 984 if (!retval) { 985 res = process_switches(flag_val, flag_set); 986 retval += res; 987 } 988 989 log_msg(3, "Switches:-"); 990 for (i = 0; i < 128; i++) { 991 if (flag_set[i]) { 992 log_msg(3, "-%c %s", i, flag_val[i]); 993 } 994 } 995 bkpinfo->boot_type = mr_boot_type(); 996 997 return (retval); 994 998 } 995 999 … … 1058 1062 1059 1063 1060 /**1061 * Turn signal-trapping on or off.1062 * @param on If TRUE, turn it on; if FALSE, turn it off (we still trap it, just don't do as much).1063 */1064 void set_signals(int on)1065 {1066 int signals[] = { SIGTERM, SIGHUP, SIGTRAP, SIGABRT, SIGINT, SIGKILL, SIGSTOP, 0 };1067 int i;1068 1069 signal(SIGPIPE, sigpipe_occurred);1070 for (i = 0; signals[i]; i++) {1071 if (on) {1072 signal(signals[i], terminate_daemon);1073 } else {1074 signal(signals[i], termination_in_progress);1075 }1076 }1077 }1078 1079 1080 1081 1064 1082 1065 /** … … 1091 1074 } 1092 1075 1076 1077 1078 /** 1079 * Turn signal-trapping on or off. 1080 * @param on If TRUE, turn it on; if FALSE, turn it off (we still trap it, just don't do as much). 1081 */ 1082 void set_signals(int on) 1083 { 1084 int signals[] = { SIGTERM, SIGHUP, SIGTRAP, SIGABRT, SIGINT, SIGKILL, SIGSTOP, 0 }; 1085 int i; 1086 1087 signal(SIGPIPE, sigpipe_occurred); 1088 for (i = 0; signals[i]; i++) { 1089 if (on) { 1090 signal(signals[i], terminate_daemon); 1091 } else { 1092 signal(signals[i], termination_in_progress); 1093 } 1094 } 1095 } 1096 1093 1097 /* @} - end of cliGroup */
Note:
See TracChangeset
for help on using the changeset viewer.