From: Radosław Korzeniewski Date: Mon, 25 Oct 2021 19:26:16 +0000 (+0200) Subject: pluginlib: Update pluginclass to better handle listing. X-Git-Tag: Beta-15.0.0~793 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=32a05f75fafb0cb2f8f12a0b13bb3e8f432bf1a2;p=thirdparty%2Fbacula.git pluginlib: Update pluginclass to better handle listing. --- diff --git a/bacula/src/plugins/fd/pluginlib/pluginclass.cpp b/bacula/src/plugins/fd/pluginlib/pluginclass.cpp index 787aa787e..8607b5daa 100644 --- a/bacula/src/plugins/fd/pluginlib/pluginclass.cpp +++ b/bacula/src/plugins/fd/pluginlib/pluginclass.cpp @@ -289,19 +289,29 @@ namespace pluginlib continue; } /* scan for listing parameter, so the estimate job should be executed as a Listing procedure */ - if (EstimateFull == mode && bstrcmp(parser.argk[i], "listing")){ + if (EstimateFull == mode && bstrcmp(parser.argk[i], "listing")) + { /* we have a listing parameter which for estimate means .ls command */ - mode = Listing; DMSG0(ctx, DINFO, "listing procedure param found\n"); - continue; - } - /* scan for query parameter, so the estimate job should be executed as a QueryParam procedure */ - if (EstimateFull == mode && strcasecmp(parser.argk[i], "query") == 0){ - /* found, so check the value if provided */ - if (parser.argv[i]){ - mode = QueryParams; - DMSG0(ctx, DINFO, "query procedure param found\n"); + mode = Listing; + const char **table = get_listing_top_struct(); + if (table) + { + pm_strcpy(m_listing_query, parser.argv[i]); + m_listing_top_nr = 0; + for (int func = 0; table[func]; func++) + { + if (bstrcmp(parser.argv[i], table[func]) || (*parser.argv[i] == '/' && bstrcmp(parser.argv[i] + 1, table[func]))) + { + DMSG2(ctx, DDEBUG, "listing data: %s %d\n", table[func], func); + m_listing_func = func; + m_listing_top_nr = -1; + break; + } + } } + DMSG2(ctx, DDEBUG, "m_listing_top_nr: %d m_listing_func: %d\n", m_listing_top_nr, m_listing_func); + continue; } /* handle it with pluginctx */ bRC status = pluginctx_parse_parameter(ctx, parser.argk[i], parser.argv[i]); @@ -568,6 +578,42 @@ namespace pluginlib return bRC_OK; } + if (mode == Listing) + { + if (m_listing_top_nr >= 0) + { + const char **table = get_listing_top_struct(); + if (table) + { + DMSG1(ctx, DINFO, "m_listing_top_nr: %d\n", m_listing_top_nr); + const char *table_name = (char *)table[m_listing_top_nr]; + if (table_name) + { + // handle listing top + m_listing_top_nr++; + sp->fname = (char *)table_name; + sp->type = FT_DIREND; + sp->statp.st_size = 0; + sp->statp.st_nlink = 1; + sp->statp.st_uid = 0; + sp->statp.st_gid = 0; + sp->statp.st_mode = 040750; + sp->statp.st_blksize = 4096; + sp->statp.st_blocks = 1; + sp->statp.st_atime = sp->statp.st_mtime = sp->statp.st_ctime = time(NULL); + return bRC_OK; + } else { + m_listing_top_nr = -1; + return bRC_Max; + } + } else { + DMSG0(ctx, DERROR, "Listing is not enabled for this plugin\n"); + JMSG0(ctx, DERROR, "Listing is not enabled for this plugin\n"); + return bRC_Error; + } + } + } + bRC status = perform_start_backup_file(ctx, sp); DMSG2(ctx, DINFO, "StartBackup: %s %ld\n", sp->fname, sp->statp.st_size); @@ -599,6 +645,11 @@ namespace pluginlib return bRC_More; } + if (mode == Listing && m_listing_top_nr >= 0) + { + return bRC_More; + } + bRC status = perform_end_backup_file(ctx); if (status == bRC_More) { DMSG1(ctx, DINFO, "Nextfile %s backup!\n", fname.c_str()); @@ -738,17 +789,21 @@ namespace pluginlib bRC PLUGINBCLASS::queryParameter(bpContext *ctx, struct query_pkt *qp) { // check if it is our Plugin command - if (!isourplugincommand(PLUGINPREFIX, qp->command) != 0){ + if (!isourplugincommand(PLUGINPREFIX, qp->command) != 0) + { // it is not our plugin prefix return bRC_OK; } CHECK_JOB_CANCELLED; - if (mode != QueryParams) { + if (mode != QueryParams) // TODO: do we really need this? + { mode = QueryParams; } + pluginctx_switch_command(qp->command); + return perform_query_parameter(ctx, qp); } diff --git a/bacula/src/plugins/fd/pluginlib/pluginclass.h b/bacula/src/plugins/fd/pluginlib/pluginclass.h index 2988ae22b..78447bcdc 100644 --- a/bacula/src/plugins/fd/pluginlib/pluginclass.h +++ b/bacula/src/plugins/fd/pluginlib/pluginclass.h @@ -108,7 +108,11 @@ namespace pluginlib parser(), execpath(PM_FNAME), workingpath(PM_FNAME), - job_cancelled(false) + job_cancelled(false), + accurate_mode(0), + m_listing_query(PM_NAME), + m_listing_top_nr(-1), + m_listing_func(-1) {} #if __cplusplus > 201103L PLUGINBCLASS() = delete; @@ -135,6 +139,9 @@ namespace pluginlib POOL_MEM workingpath; /// ready to use path for bacula working directory bool job_cancelled; /// it signal the metaplugin that job was cancelled int accurate_mode; /// if the job is accurate + POOL_MEM m_listing_query; /// + int m_listing_top_nr; /// + int m_listing_func; /// virtual bRC parse_plugin_config(bpContext *ctx, restore_object_pkt *rop) { return bRC_OK; } virtual bRC parse_plugin_command(bpContext *ctx, const char *command); @@ -181,7 +188,7 @@ namespace pluginlib virtual bRC perform_end_restore_file(bpContext *ctx) { return bRC_OK; } virtual bRC perform_cancel_command(bpContext *ctx) { return bRC_OK; } - // virtual int check_ini_param(char *param); + virtual const char **get_listing_top_struct() noexcept { return NULL; } virtual void pluginctx_switch_command(const char *command) {} virtual void pluginctx_clear_abort_on_error() {}