PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/amanda/tags/amanda252p1/client-src/client_util.c

#
C | 862 lines | 810 code | 22 blank | 30 comment | 37 complexity | c0a4bc5e0142cec6783b4e838071c343 MD5 | raw file
  1. /*
  2. * Amanda, The Advanced Maryland Automatic Network Disk Archiver
  3. * Copyright (c) 1991-1998 University of Maryland at College Park
  4. * All Rights Reserved.
  5. *
  6. * Permission to use, copy, modify, distribute, and sell this software and its
  7. * documentation for any purpose is hereby granted without fee, provided that
  8. * the above copyright notice appear in all copies and that both that
  9. * copyright notice and this permission notice appear in supporting
  10. * documentation, and that the name of U.M. not be used in advertising or
  11. * publicity pertaining to distribution of the software without specific,
  12. * written prior permission. U.M. makes no representations about the
  13. * suitability of this software for any purpose. It is provided "as is"
  14. * without express or implied warranty.
  15. *
  16. * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
  18. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  21. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22. *
  23. * Authors: the Amanda Development Team. Its members are listed in a
  24. * file named AUTHORS, in the root directory of this distribution.
  25. */
  26. /*
  27. * $Id: client_util.c,v 1.34 2006/05/25 01:47:11 johnfranks Exp $
  28. *
  29. */
  30. #include "amanda.h"
  31. #include "conffile.h"
  32. #include "client_util.h"
  33. #include "getfsent.h"
  34. #include "util.h"
  35. #include "pipespawn.h"
  36. #define MAXMAXDUMPS 16
  37. static int add_exclude(FILE *file_exclude, char *aexc, int verbose);
  38. static int add_include(char *disk, char *device, FILE *file_include, char *ainc, int verbose);
  39. static char *build_name(char *disk, char *exin, int verbose);
  40. static char *get_name(char *diskname, char *exin, time_t t, int n);
  41. char *
  42. fixup_relative(
  43. char * name,
  44. char * device)
  45. {
  46. char *newname;
  47. if(*name != '/') {
  48. char *dirname = amname_to_dirname(device);
  49. newname = vstralloc(dirname, "/", name , NULL);
  50. amfree(dirname);
  51. }
  52. else {
  53. newname = stralloc(name);
  54. }
  55. return newname;
  56. }
  57. static char *
  58. get_name(
  59. char * diskname,
  60. char * exin,
  61. time_t t,
  62. int n)
  63. {
  64. char number[NUM_STR_SIZE];
  65. char *filename;
  66. char *ts;
  67. ts = construct_timestamp(&t);
  68. if(n == 0)
  69. number[0] = '\0';
  70. else
  71. snprintf(number, SIZEOF(number), "%03d", n - 1);
  72. filename = vstralloc(get_pname(), ".", diskname, ".", ts, number, ".",
  73. exin, NULL);
  74. amfree(ts);
  75. return filename;
  76. }
  77. static char *
  78. build_name(
  79. char * disk,
  80. char * exin,
  81. int verbose)
  82. {
  83. int n;
  84. int fd;
  85. char *filename = NULL;
  86. char *afilename = NULL;
  87. char *diskname;
  88. time_t curtime;
  89. char *dbgdir;
  90. char *e = NULL;
  91. DIR *d;
  92. struct dirent *entry;
  93. char *test_name;
  94. size_t match_len, d_name_len;
  95. char *quoted;
  96. time(&curtime);
  97. diskname = sanitise_filename(disk);
  98. dbgdir = stralloc2(AMANDA_TMPDIR, "/");
  99. if((d = opendir(AMANDA_TMPDIR)) == NULL) {
  100. error("open debug directory \"%s\": %s",
  101. AMANDA_TMPDIR, strerror(errno));
  102. /*NOTREACHED*/
  103. }
  104. test_name = get_name(diskname, exin,
  105. curtime - (AMANDA_DEBUG_DAYS * 24 * 60 * 60), 0);
  106. match_len = strlen(get_pname()) + strlen(diskname) + 2;
  107. while((entry = readdir(d)) != NULL) {
  108. if(is_dot_or_dotdot(entry->d_name)) {
  109. continue;
  110. }
  111. d_name_len = strlen(entry->d_name);
  112. if(strncmp(test_name, entry->d_name, match_len) != 0
  113. || d_name_len < match_len + 14 + 8
  114. || strcmp(entry->d_name+ d_name_len - 7, exin) != 0) {
  115. continue; /* not one of our files */
  116. }
  117. if(strcmp(entry->d_name, test_name) < 0) {
  118. e = newvstralloc(e, dbgdir, entry->d_name, NULL);
  119. (void) unlink(e); /* get rid of old file */
  120. }
  121. }
  122. amfree(test_name);
  123. amfree(e);
  124. closedir(d);
  125. n=0;
  126. do {
  127. filename = get_name(diskname, exin, curtime, n);
  128. afilename = newvstralloc(afilename, dbgdir, filename, NULL);
  129. if((fd=open(afilename, O_WRONLY|O_CREAT|O_APPEND, 0600)) < 0){
  130. amfree(afilename);
  131. n++;
  132. }
  133. else {
  134. close(fd);
  135. }
  136. amfree(filename);
  137. } while(!afilename && n < 1000);
  138. if(afilename == NULL) {
  139. filename = get_name(diskname, exin, curtime, 0);
  140. afilename = newvstralloc(afilename, dbgdir, filename, NULL);
  141. quoted = quote_string(afilename);
  142. dbprintf(("%s: Cannot create %s (%s)\n",
  143. debug_prefix_time(NULL), quoted, strerror(errno)));
  144. if(verbose) {
  145. printf("ERROR [cannot create %s (%s)]\n",
  146. quoted, strerror(errno));
  147. }
  148. amfree(quoted);
  149. amfree(afilename);
  150. amfree(filename);
  151. }
  152. amfree(dbgdir);
  153. amfree(diskname);
  154. return afilename;
  155. }
  156. static int
  157. add_exclude(
  158. FILE * file_exclude,
  159. char * aexc,
  160. int verbose)
  161. {
  162. size_t l;
  163. char *quoted, *file;
  164. (void)verbose; /* Quiet unused parameter warning */
  165. l = strlen(aexc);
  166. if(aexc[l-1] == '\n') {
  167. aexc[l-1] = '\0';
  168. l--;
  169. }
  170. file = quoted = quote_string(aexc);
  171. if (*file == '"') {
  172. file[strlen(file) - 1] = '\0';
  173. file++;
  174. }
  175. fprintf(file_exclude, "%s\n", file);
  176. amfree(quoted);
  177. return 1;
  178. }
  179. static int
  180. add_include(
  181. char * disk,
  182. char * device,
  183. FILE * file_include,
  184. char * ainc,
  185. int verbose)
  186. {
  187. size_t l;
  188. int nb_exp=0;
  189. char *quoted, *file;
  190. (void)disk; /* Quiet unused parameter warning */
  191. l = strlen(ainc);
  192. if(ainc[l-1] == '\n') {
  193. ainc[l-1] = '\0';
  194. l--;
  195. }
  196. if (strncmp(ainc, "./", 2) != 0) {
  197. quoted = quote_string(ainc);
  198. dbprintf(("%s: include must start with './' (%s)\n",
  199. debug_prefix_time(NULL), quoted));
  200. if(verbose) {
  201. printf("ERROR [include must start with './' (%s)]\n", quoted);
  202. }
  203. amfree(quoted);
  204. }
  205. else {
  206. char *incname = ainc+2;
  207. if(strchr(incname, '/')) {
  208. file = quoted = quote_string(ainc);
  209. if (*file == '"') {
  210. file[strlen(file) - 1] = '\0';
  211. file++;
  212. }
  213. fprintf(file_include, "%s\n", file);
  214. amfree(quoted);
  215. nb_exp++;
  216. }
  217. else {
  218. char *regex;
  219. DIR *d;
  220. struct dirent *entry;
  221. regex = glob_to_regex(incname);
  222. if((d = opendir(device)) == NULL) {
  223. quoted = quote_string(device);
  224. dbprintf(("%s: Can't open disk %s\n",
  225. debug_prefix_time(NULL), quoted));
  226. if(verbose) {
  227. printf("ERROR [Can't open disk %s]\n", quoted);
  228. }
  229. amfree(quoted);
  230. }
  231. else {
  232. while((entry = readdir(d)) != NULL) {
  233. if(is_dot_or_dotdot(entry->d_name)) {
  234. continue;
  235. }
  236. if(match(regex, entry->d_name)) {
  237. incname = vstralloc("./", entry->d_name, NULL);
  238. file = quoted = quote_string(incname);
  239. if (*file == '"') {
  240. file[strlen(file) - 1] = '\0';
  241. file++;
  242. }
  243. fprintf(file_include, "%s\n", file);
  244. amfree(quoted);
  245. amfree(incname);
  246. nb_exp++;
  247. }
  248. }
  249. closedir(d);
  250. }
  251. amfree(regex);
  252. }
  253. }
  254. return nb_exp;
  255. }
  256. char *
  257. build_exclude(
  258. char * disk,
  259. char * device,
  260. option_t * options,
  261. int verbose)
  262. {
  263. char *filename;
  264. FILE *file_exclude;
  265. FILE *exclude;
  266. char *aexc;
  267. sle_t *excl;
  268. int nb_exclude = 0;
  269. char *quoted;
  270. if(options->exclude_file) nb_exclude += options->exclude_file->nb_element;
  271. if(options->exclude_list) nb_exclude += options->exclude_list->nb_element;
  272. if(nb_exclude == 0) return NULL;
  273. if((filename = build_name(disk, "exclude", verbose)) != NULL) {
  274. if((file_exclude = fopen(filename,"w")) != NULL) {
  275. if(options->exclude_file) {
  276. for(excl = options->exclude_file->first; excl != NULL;
  277. excl = excl->next) {
  278. add_exclude(file_exclude, excl->name,
  279. verbose && options->exclude_optional == 0);
  280. }
  281. }
  282. if(options->exclude_list) {
  283. for(excl = options->exclude_list->first; excl != NULL;
  284. excl = excl->next) {
  285. char *exclname = fixup_relative(excl->name, device);
  286. if((exclude = fopen(exclname, "r")) != NULL) {
  287. while ((aexc = agets(exclude)) != NULL) {
  288. if (aexc[0] == '\0') {
  289. amfree(aexc);
  290. continue;
  291. }
  292. add_exclude(file_exclude, aexc,
  293. verbose && options->exclude_optional == 0);
  294. amfree(aexc);
  295. }
  296. fclose(exclude);
  297. }
  298. else {
  299. quoted = quote_string(exclname);
  300. dbprintf(("%s: Can't open exclude file %s (%s)\n",
  301. debug_prefix_time(NULL),
  302. quoted, strerror(errno)));
  303. if(verbose && (options->exclude_optional == 0 ||
  304. errno != ENOENT)) {
  305. printf("ERROR [Can't open exclude file %s (%s)]\n",
  306. quoted, strerror(errno));
  307. }
  308. amfree(quoted);
  309. }
  310. amfree(exclname);
  311. }
  312. }
  313. fclose(file_exclude);
  314. }
  315. else {
  316. quoted = quote_string(filename);
  317. dbprintf(("%s: Can't create exclude file %s (%s)\n",
  318. debug_prefix_time(NULL),
  319. quoted, strerror(errno)));
  320. if(verbose) {
  321. printf("ERROR [Can't create exclude file %s (%s)]\n",
  322. quoted, strerror(errno));
  323. }
  324. amfree(quoted);
  325. }
  326. }
  327. return filename;
  328. }
  329. char *
  330. build_include(
  331. char * disk,
  332. char * device,
  333. option_t * options,
  334. int verbose)
  335. {
  336. char *filename;
  337. FILE *file_include;
  338. FILE *include;
  339. char *ainc = NULL;
  340. sle_t *incl;
  341. int nb_include = 0;
  342. int nb_exp = 0;
  343. char *quoted;
  344. if(options->include_file) nb_include += options->include_file->nb_element;
  345. if(options->include_list) nb_include += options->include_list->nb_element;
  346. if(nb_include == 0) return NULL;
  347. if((filename = build_name(disk, "include", verbose)) != NULL) {
  348. if((file_include = fopen(filename,"w")) != NULL) {
  349. if(options->include_file) {
  350. for(incl = options->include_file->first; incl != NULL;
  351. incl = incl->next) {
  352. nb_exp += add_include(disk, device, file_include,
  353. incl->name,
  354. verbose && options->include_optional == 0);
  355. }
  356. }
  357. if(options->include_list) {
  358. for(incl = options->include_list->first; incl != NULL;
  359. incl = incl->next) {
  360. char *inclname = fixup_relative(incl->name, device);
  361. if((include = fopen(inclname, "r")) != NULL) {
  362. while ((ainc = agets(include)) != NULL) {
  363. if (ainc[0] == '\0') {
  364. amfree(ainc);
  365. continue;
  366. }
  367. nb_exp += add_include(disk, device,
  368. file_include, ainc,
  369. verbose && options->include_optional == 0);
  370. amfree(ainc);
  371. }
  372. fclose(include);
  373. }
  374. else {
  375. quoted = quote_string(inclname);
  376. dbprintf(("%s: Can't open include file %s (%s)\n",
  377. debug_prefix_time(NULL), quoted, strerror(errno)));
  378. if(verbose && (options->include_optional == 0 ||
  379. errno != ENOENT)) {
  380. printf("ERROR [Can't open include file %s (%s)]\n",
  381. quoted, strerror(errno));
  382. }
  383. amfree(quoted);
  384. }
  385. amfree(inclname);
  386. }
  387. }
  388. fclose(file_include);
  389. }
  390. else {
  391. quoted = quote_string(filename);
  392. dbprintf(("%s: Can't create include file %s (%s)\n",
  393. debug_prefix_time(NULL), quoted, strerror(errno)));
  394. if(verbose) {
  395. printf("ERROR [Can't create include file %s (%s)]\n",
  396. quoted, strerror(errno));
  397. }
  398. amfree(quoted);
  399. }
  400. }
  401. if(nb_exp == 0) {
  402. quoted = quote_string(disk);
  403. dbprintf(("%s: No include for %s\n", debug_prefix_time(NULL), quoted));
  404. if(verbose && options->include_optional == 0) {
  405. printf("ERROR [No include for %s]\n", quoted);
  406. }
  407. amfree(quoted);
  408. }
  409. return filename;
  410. }
  411. void
  412. init_options(
  413. option_t *options)
  414. {
  415. options->str = NULL;
  416. options->compress = COMP_NONE;
  417. options->srvcompprog = NULL;
  418. options->clntcompprog = NULL;
  419. options->encrypt = ENCRYPT_NONE;
  420. options->srv_encrypt = NULL;
  421. options->clnt_encrypt = NULL;
  422. options->srv_decrypt_opt = NULL;
  423. options->clnt_decrypt_opt = NULL;
  424. options->no_record = 0;
  425. options->createindex = 0;
  426. options->auth = NULL;
  427. options->exclude_file = NULL;
  428. options->exclude_list = NULL;
  429. options->include_file = NULL;
  430. options->include_list = NULL;
  431. options->exclude_optional = 0;
  432. options->include_optional = 0;
  433. }
  434. option_t *
  435. parse_options(
  436. char *str,
  437. char *disk,
  438. char *device,
  439. am_feature_t *fs,
  440. int verbose)
  441. {
  442. char *exc;
  443. char *inc;
  444. option_t *options;
  445. char *p, *tok;
  446. char *quoted;
  447. (void)disk; /* Quiet unused parameter warning */
  448. (void)device; /* Quiet unused parameter warning */
  449. options = alloc(SIZEOF(option_t));
  450. init_options(options);
  451. options->str = stralloc(str);
  452. p = stralloc(str);
  453. tok = strtok(p,";");
  454. while (tok != NULL) {
  455. if(am_has_feature(fs, fe_options_auth)
  456. && BSTRNCMP(tok,"auth=") == 0) {
  457. if(options->auth != NULL) {
  458. quoted = quote_string(tok + 5);
  459. dbprintf(("%s: multiple auth option %s\n",
  460. debug_prefix_time(NULL), quoted));
  461. if(verbose) {
  462. printf("ERROR [multiple auth option %s]\n", quoted);
  463. }
  464. amfree(quoted);
  465. }
  466. options->auth = stralloc(&tok[5]);
  467. }
  468. else if(am_has_feature(fs, fe_options_bsd_auth)
  469. && BSTRNCMP(tok, "bsd-auth") == 0) {
  470. if(options->auth != NULL) {
  471. dbprintf(("%s: multiple auth option\n",
  472. debug_prefix_time(NULL)));
  473. if(verbose) {
  474. printf("ERROR [multiple auth option]\n");
  475. }
  476. }
  477. options->auth = stralloc("bsd");
  478. }
  479. else if(am_has_feature(fs, fe_options_krb4_auth)
  480. && BSTRNCMP(tok, "krb4-auth") == 0) {
  481. if(options->auth != NULL) {
  482. dbprintf(("%s: multiple auth option\n",
  483. debug_prefix_time(NULL)));
  484. if(verbose) {
  485. printf("ERROR [multiple auth option]\n");
  486. }
  487. }
  488. options->auth = stralloc("krb4");
  489. }
  490. else if(BSTRNCMP(tok, "compress-fast") == 0) {
  491. if(options->compress != COMP_NONE) {
  492. dbprintf(("%s: multiple compress option\n",
  493. debug_prefix_time(NULL)));
  494. if(verbose) {
  495. printf("ERROR [multiple compress option]\n");
  496. }
  497. }
  498. options->compress = COMP_FAST;
  499. }
  500. else if(BSTRNCMP(tok, "compress-best") == 0) {
  501. if(options->compress != COMP_NONE) {
  502. dbprintf(("%s: multiple compress option\n",
  503. debug_prefix_time(NULL)));
  504. if(verbose) {
  505. printf("ERROR [multiple compress option]\n");
  506. }
  507. }
  508. options->compress = COMP_BEST;
  509. }
  510. else if(BSTRNCMP(tok, "srvcomp-fast") == 0) {
  511. if(options->compress != COMP_NONE) {
  512. dbprintf(("%s: multiple compress option\n",
  513. debug_prefix_time(NULL)));
  514. if(verbose) {
  515. printf("ERROR [multiple compress option]\n");
  516. }
  517. }
  518. options->compress = COMP_SERVER_FAST;
  519. }
  520. else if(BSTRNCMP(tok, "srvcomp-best") == 0) {
  521. if(options->compress != COMP_NONE) {
  522. dbprintf(("%s: multiple compress option\n",
  523. debug_prefix_time(NULL)));
  524. if(verbose) {
  525. printf("ERROR [multiple compress option]\n");
  526. }
  527. }
  528. options->compress = COMP_SERVER_BEST;
  529. }
  530. else if(BSTRNCMP(tok, "srvcomp-cust=") == 0) {
  531. if(options->compress != COMP_NONE) {
  532. dbprintf(("%s: multiple compress option\n",
  533. debug_prefix_time(NULL)));
  534. if(verbose) {
  535. printf("ERROR [multiple compress option]\n");
  536. }
  537. }
  538. options->srvcompprog = stralloc(tok + SIZEOF("srvcomp-cust=") -1);
  539. options->compress = COMP_SERVER_CUST;
  540. }
  541. else if(BSTRNCMP(tok, "comp-cust=") == 0) {
  542. if(options->compress != COMP_NONE) {
  543. dbprintf(("%s: multiple compress option\n",
  544. debug_prefix_time(NULL)));
  545. if(verbose) {
  546. printf("ERROR [multiple compress option]\n");
  547. }
  548. }
  549. options->clntcompprog = stralloc(tok + SIZEOF("comp-cust=") -1);
  550. options->compress = COMP_CUST;
  551. /* parse encryption options */
  552. }
  553. else if(BSTRNCMP(tok, "encrypt-serv-cust=") == 0) {
  554. if(options->encrypt != ENCRYPT_NONE) {
  555. dbprintf(("%s: multiple encrypt option\n",
  556. debug_prefix_time(NULL)));
  557. if(verbose) {
  558. printf("ERROR [multiple encrypt option]\n");
  559. }
  560. }
  561. options->srv_encrypt = stralloc(tok + SIZEOF("encrypt-serv-cust=") -1);
  562. options->encrypt = ENCRYPT_SERV_CUST;
  563. }
  564. else if(BSTRNCMP(tok, "encrypt-cust=") == 0) {
  565. if(options->encrypt != ENCRYPT_NONE) {
  566. dbprintf(("%s: multiple encrypt option\n",
  567. debug_prefix_time(NULL)));
  568. if(verbose) {
  569. printf("ERROR [multiple encrypt option]\n");
  570. }
  571. }
  572. options->clnt_encrypt= stralloc(tok + SIZEOF("encrypt-cust=") -1);
  573. options->encrypt = ENCRYPT_CUST;
  574. }
  575. else if(BSTRNCMP(tok, "server-decrypt-option=") == 0) {
  576. options->srv_decrypt_opt = stralloc(tok + SIZEOF("server-decrypt-option=") -1);
  577. }
  578. else if(BSTRNCMP(tok, "client-decrypt-option=") == 0) {
  579. options->clnt_decrypt_opt = stralloc(tok + SIZEOF("client-decrypt-option=") -1);
  580. }
  581. else if(BSTRNCMP(tok, "no-record") == 0) {
  582. if(options->no_record != 0) {
  583. dbprintf(("%s: multiple no-record option\n",
  584. debug_prefix_time(NULL)));
  585. if(verbose) {
  586. printf("ERROR [multiple no-record option]\n");
  587. }
  588. }
  589. options->no_record = 1;
  590. }
  591. else if(BSTRNCMP(tok, "index") == 0) {
  592. if(options->createindex != 0) {
  593. dbprintf(("%s: multiple index option\n",
  594. debug_prefix_time(NULL)));
  595. if(verbose) {
  596. printf("ERROR [multiple index option]\n");
  597. }
  598. }
  599. options->createindex = 1;
  600. }
  601. else if(BSTRNCMP(tok, "exclude-optional") == 0) {
  602. if(options->exclude_optional != 0) {
  603. dbprintf(("%s: multiple exclude-optional option\n",
  604. debug_prefix_time(NULL)));
  605. if(verbose) {
  606. printf("ERROR [multiple exclude-optional option]\n");
  607. }
  608. }
  609. options->exclude_optional = 1;
  610. }
  611. else if(strcmp(tok, "include-optional") == 0) {
  612. if(options->include_optional != 0) {
  613. dbprintf(("%s: multiple include-optional option\n",
  614. debug_prefix_time(NULL)));
  615. if(verbose) {
  616. printf("ERROR [multiple include-optional option]\n");
  617. }
  618. }
  619. options->include_optional = 1;
  620. }
  621. else if(BSTRNCMP(tok,"exclude-file=") == 0) {
  622. exc = unquote_string(&tok[13]);
  623. options->exclude_file = append_sl(options->exclude_file, exc);
  624. amfree(exc);
  625. }
  626. else if(BSTRNCMP(tok,"exclude-list=") == 0) {
  627. exc = unquote_string(&tok[13]);
  628. options->exclude_list = append_sl(options->exclude_list, exc);
  629. amfree(exc);
  630. }
  631. else if(BSTRNCMP(tok,"include-file=") == 0) {
  632. inc = unquote_string(&tok[13]);
  633. options->include_file = append_sl(options->include_file, inc);
  634. amfree(inc);
  635. }
  636. else if(BSTRNCMP(tok,"include-list=") == 0) {
  637. inc = unquote_string(&tok[13]);
  638. options->include_list = append_sl(options->include_list, inc);
  639. amfree(inc);
  640. }
  641. else if(strcmp(tok,"|") != 0) {
  642. quoted = quote_string(tok);
  643. dbprintf(("%s: unknown option %s\n",
  644. debug_prefix_time(NULL), quoted));
  645. if(verbose) {
  646. printf("ERROR [unknown option: %s]\n", quoted);
  647. }
  648. amfree(quoted);
  649. }
  650. tok = strtok(NULL, ";");
  651. }
  652. amfree(p);
  653. return options;
  654. }
  655. void
  656. output_tool_property(
  657. FILE *tool,
  658. option_t *options)
  659. {
  660. sle_t *sle;
  661. char *q;
  662. if (!is_empty_sl(options->exclude_file)) {
  663. for(sle = options->exclude_file->first ; sle != NULL; sle=sle->next) {
  664. q = quote_string(sle->name);
  665. fprintf(tool, "EXCLUDE-FILE %s\n", q);
  666. amfree(q);
  667. }
  668. }
  669. if (!is_empty_sl(options->exclude_list)) {
  670. for(sle = options->exclude_list->first ; sle != NULL; sle=sle->next) {
  671. q = quote_string(sle->name);
  672. fprintf(tool, "EXCLUDE-LIST %s\n", q);
  673. amfree(q);
  674. }
  675. }
  676. if (!is_empty_sl(options->include_file)) {
  677. for(sle = options->include_file->first ; sle != NULL; sle=sle->next) {
  678. q = quote_string(sle->name);
  679. fprintf(tool, "INCLUDE-FILE %s\n", q);
  680. amfree(q);
  681. }
  682. }
  683. if (!is_empty_sl(options->include_list)) {
  684. for(sle = options->include_list->first ; sle != NULL; sle=sle->next) {
  685. q = quote_string(sle->name);
  686. fprintf(tool, "INCLUDE-LIST %s\n", q);
  687. amfree(q);
  688. }
  689. }
  690. if (!is_empty_sl(options->exclude_file) ||
  691. !is_empty_sl(options->exclude_list)) {
  692. if (options->exclude_optional)
  693. fprintf(tool, "EXCLUDE-OPTIONAL YES\n");
  694. else
  695. fprintf(tool, "EXCLUDE-OPTIONAL NO\n");
  696. }
  697. if (!is_empty_sl(options->include_file) ||
  698. !is_empty_sl(options->include_list)) {
  699. if (options->include_optional)
  700. fprintf(tool, "INCLUDE-OPTIONAL YES\n");
  701. else
  702. fprintf(tool, "INCLUDE-OPTIONAL NO\n");
  703. }
  704. }
  705. backup_support_option_t *
  706. backup_support_option(
  707. char *program,
  708. g_option_t *g_options,
  709. char *disk,
  710. char *amdevice)
  711. {
  712. pid_t supportpid;
  713. int supportin, supportout, supporterr;
  714. char *cmd;
  715. char **argvchild;
  716. int i;
  717. FILE *streamout;
  718. char *line;
  719. backup_support_option_t *bsu;
  720. cmd = vstralloc(DUMPER_DIR, "/", program, NULL);
  721. argvchild = malloc(5 * SIZEOF(char *));
  722. i = 0;
  723. argvchild[i++] = program;
  724. argvchild[i++] = "support";
  725. if (g_options->config) {
  726. argvchild[i++] = "--config";
  727. argvchild[i++] = g_options->config;
  728. }
  729. if (g_options->hostname) {
  730. argvchild[i++] = "--host";
  731. argvchild[i++] = g_options->hostname;
  732. }
  733. if (disk) {
  734. argvchild[i++] = "--disk";
  735. argvchild[i++] = disk;
  736. }
  737. if (amdevice) {
  738. argvchild[i++] = "--device";
  739. argvchild[i++] = amdevice;
  740. }
  741. argvchild[i++] = NULL;
  742. supporterr = fileno(stderr);
  743. supportpid = pipespawnv(cmd, STDIN_PIPE|STDOUT_PIPE, &supportin,
  744. &supportout, &supporterr, argvchild);
  745. aclose(supportin);
  746. bsu = malloc(SIZEOF(*bsu));
  747. memset(bsu, '\0', SIZEOF(*bsu));
  748. streamout = fdopen(supportout, "r");
  749. while((line = agets(streamout)) != NULL) {
  750. dbprintf(("support line: %s\n", line));
  751. if (strncmp(line,"CONFIG ", 7) == 0) {
  752. if (strcmp(line+7, "YES") == 0)
  753. bsu->config = 1;
  754. } else if (strncmp(line,"HOST ", 5) == 0) {
  755. if (strcmp(line+5, "YES") == 0)
  756. bsu->host = 1;
  757. } else if (strncmp(line,"DISK ", 5) == 0) {
  758. if (strcmp(line+5, "YES") == 0)
  759. bsu->host = 1;
  760. } else if (strncmp(line,"INDEX-LINE ", 11) == 0) {
  761. if (strcmp(line+11, "YES") == 0)
  762. bsu->index_line = 1;
  763. } else if (strncmp(line,"INDEX-XML ", 10) == 0) {
  764. if (strcmp(line+10, "YES") == 0)
  765. bsu->index_xml = 1;
  766. } else if (strncmp(line,"MESSAGE-LINE ", 13) == 0) {
  767. if (strcmp(line+13, "YES") == 0)
  768. bsu->message_line = 1;
  769. } else if (strncmp(line,"MESSAGE-XML ", 12) == 0) {
  770. if (strcmp(line+12, "YES") == 0)
  771. bsu->message_xml = 1;
  772. } else if (strncmp(line,"RECORD ", 7) == 0) {
  773. if (strcmp(line+7, "YES") == 0)
  774. bsu->record = 1;
  775. } else if (strncmp(line,"INCLUDE-FILE ", 13) == 0) {
  776. if (strcmp(line+13, "YES") == 0)
  777. bsu->include_file = 1;
  778. } else if (strncmp(line,"INCLUDE-LIST ", 13) == 0) {
  779. if (strcmp(line+13, "YES") == 0)
  780. bsu->include_list = 1;
  781. } else if (strncmp(line,"EXCLUDE-FILE ", 13) == 0) {
  782. if (strcmp(line+13, "YES") == 0)
  783. bsu->exclude_file = 1;
  784. } else if (strncmp(line,"EXCLUDE-LIST ", 13) == 0) {
  785. if (strcmp(line+13, "YES") == 0)
  786. bsu->exclude_list = 1;
  787. } else if (strncmp(line,"COLLECTION ", 11) == 0) {
  788. if (strcmp(line+11, "YES") == 0)
  789. bsu->collection = 1;
  790. } else if (strncmp(line,"MAX-LEVEL ", 10) == 0) {
  791. bsu->max_level = atoi(line+10);
  792. } else {
  793. dbprintf(("Invalid support line: %s\n", line));
  794. }
  795. amfree(line);
  796. }
  797. aclose(supportout);
  798. return NULL;
  799. }