+ int level;
+ int i;
+ int levels[DUMP_LEVELS];
+ int nb_level = 0;
+ backup_support_option_t *bsu;
+ GPtrArray *errarray;
+ estimatelist_t el;
+ estimate_t estimate;
+ estimate_t estimate_method = ES_ES;
+ estimate_t client_method = ES_ES;
+ int has_calcsize = 0;
+ int has_client = 0;
+
+ bsu = backup_support_option(est->dle->program, g_options, est->dle->disk,
+ est->dle->device, &errarray);
+ if (!bsu) {
+ guint i;
+ for (i=0; i < errarray->len; i++) {
+ char *line;
+ char *errmsg;
+ char *qerrmsg;
+ line = g_ptr_array_index(errarray, i);
+ if(am_has_feature(g_options->features,
+ fe_rep_sendsize_quoted_error)) {
+ errmsg = g_strdup_printf(_("Application '%s': %s"),
+ est->dle->program, line);
+ qerrmsg = quote_string(errmsg);
+ for (level = 0; level < DUMP_LEVELS; level++) {
+ if (est->est[level].needestimate) {
+ g_printf(_("%s %d ERROR %s\n"),
+ est->dle->disk, level, qerrmsg);
+ dbprintf(_("%s %d ERROR %s\n"),
+ est->qamname, level, qerrmsg);
+ }
+ }
+ amfree(errmsg);
+ amfree(qerrmsg);
+ }
+ }
+ if (i == 0) { /* nothing in errarray */
+ char *errmsg;
+ char *qerrmsg;
+ errmsg = g_strdup_printf(
+ _("Application '%s': cannon execute support command"),
+ est->dle->program);
+ qerrmsg = quote_string(errmsg);
+ for (level = 0; level < DUMP_LEVELS; level++) {
+ if (est->est[level].needestimate) {
+ g_printf(_("%s %d ERROR %s\n"),
+ est->dle->disk, level, qerrmsg);
+ dbprintf(_("%s %d ERROR %s\n"),
+ est->qamname, level, qerrmsg);
+ }
+ }
+ amfree(errmsg);
+ amfree(qerrmsg);
+ }
+ for (level = 0; level < DUMP_LEVELS; level++) {
+ est->est[level].needestimate = 0;
+ }
+ g_ptr_array_free(errarray, TRUE);
+ }
+
+ if (est->dle->data_path == DATA_PATH_AMANDA &&
+ (bsu->data_path_set & DATA_PATH_AMANDA)==0) {
+ g_printf("%s %d ERROR application %s doesn't support amanda data-path\n", est->qamname, 0, est->dle->program);
+ amfree(bsu);
+ return;
+ }
+ if (est->dle->data_path == DATA_PATH_DIRECTTCP &&
+ (bsu->data_path_set & DATA_PATH_DIRECTTCP)==0) {
+ g_printf("%s %d ERROR application %s doesn't support directtcp data-path\n", est->qamname, 0, est->dle->program);
+ amfree(bsu);
+ return;
+ }
+
+ /* find estimate method to use */
+ for (el = est->dle->estimatelist; el != NULL; el = el->next) {
+ estimate = (estimate_t)GPOINTER_TO_INT(el->data);
+ if (estimate == ES_CLIENT)
+ has_client = 1;
+ if (estimate == ES_CALCSIZE)
+ has_calcsize = 1;
+ if (estimate == ES_SERVER) {
+ if (estimate_method == ES_ES)
+ estimate_method = ES_SERVER;
+ }
+ if ((estimate == ES_CLIENT && bsu->client_estimate) ||
+ (estimate == ES_CALCSIZE && bsu->calcsize)) {
+ if (client_method == ES_ES)
+ client_method = estimate;
+ if (estimate_method == ES_ES)
+ estimate_method = estimate;
+ }
+ }
+
+ for(level = 0; level < DUMP_LEVELS; level++) {
+ if (est->est[level].needestimate) {
+ if (level > bsu->max_level) {
+ /* planner will not even consider this level */
+ g_printf("%s %d SIZE %lld\n", est->qamname, level,
+ (long long)-2);
+ est->est[level].needestimate = 0;
+ dbprintf(_("Application '%s' can't estimate level %d\n"),
+ est->dle->program, level);
+ } else if (estimate_method == ES_ES) {
+ g_printf("%s %d SIZE %lld\n", est->qamname, level,
+ (long long)-2);
+ est->est[level].needestimate = 0;
+ if (am_has_feature(g_options->features,
+ fe_rep_sendsize_quoted_error)) {
+ char *errmsg, *qerrmsg;
+ if (has_client && !bsu->client_estimate &&
+ has_calcsize && !bsu->calcsize) {
+ errmsg = vstrallocf(_("Application '%s' can't do CLIENT or CALCSIZE estimate"),
+ est->dle->program);
+ } else if (has_client && !bsu->client_estimate) {
+ errmsg = vstrallocf(_("Application '%s' can't do CLIENT estimate"),
+ est->dle->program);
+ } else if (has_calcsize && !bsu->calcsize) {
+ errmsg = vstrallocf(_("Application '%s' can't do CALCSIZE estimate"),
+ est->dle->program);
+ } else {
+ errmsg = vstrallocf(_("Application '%s' can't do estimate"),
+ est->dle->program);
+ }
+ qerrmsg = quote_string(errmsg);
+ dbprintf(_("errmsg is %s\n"), errmsg);
+ g_printf("%s %d ERROR %s\n",
+ est->qamname, 0, qerrmsg);
+ amfree(errmsg);
+ amfree(qerrmsg);
+ }
+ } else if (estimate_method == ES_SERVER &&
+ (est->est[level].server || client_method == ES_ES)) {
+ /* planner will consider this level, */
+ /* but use a server-side estimate */
+ g_printf("%s %d SIZE -1\n", est->qamname, level);
+ est->est[level].needestimate = 0;
+ } else if (client_method == ES_CLIENT) {
+ levels[nb_level++] = level;
+ } else if (client_method == ES_CALCSIZE) {
+ levels[nb_level++] = level;
+ }
+ }
+ }
+
+ if (nb_level == 0) {
+ amfree(bsu);
+ return;
+ }
+
+ if (bsu->multi_estimate) {
+ for (i=0;i<nb_level;i++) {
+ dbprintf(_("getting size via application API for %s %s level %d\n"),
+ est->qamname, est->qamdevice, levels[i]);
+ }
+ getsize_application_api(est, nb_level, levels, bsu);
+
+ } else {
+ for(level = 0; level < DUMP_LEVELS; level++) {
+ if (est->est[level].needestimate) {
+ dbprintf(
+ _("getting size via application API for %s %s level %d\n"),
+ est->qamname, est->qamdevice, level);
+ levels[0] = level;
+ getsize_application_api(est, 1, levels, bsu);
+ }
+ }
+ }
+
+ amfree(bsu);