void bdb_list_jobs_for_file(JCR *jcr, const char *client, const char *fname, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
void bdb_list_job_totals(JCR *jcr, JOB_DBR *jr, DB_LIST_HANDLER sendit, void *ctx);
void bdb_list_files_for_job(JCR *jcr, uint32_t jobid, int deleted, DB_LIST_HANDLER sendit, void *ctx);
+ void bdb_list_fileevents_for_job(JCR *jcr, uint32_t jobid, char etype, DB_LIST_HANDLER sendit, void *ctx, e_list_type type);
void bdb_list_media_records(JCR *jcr, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
void bdb_list_jobmedia_records(JCR *jcr, JobId_t JobId, char *volume, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
void bdb_list_filemedia_records(JCR *jcr, JobId_t JobId, uint32_t FileIndex, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
mdb->bdb_list_job_totals(jcr, jr, sendit, ctx)
#define db_list_files_for_job(jcr, mdb, jobid, deleted, sendit, ctx) \
mdb->bdb_list_files_for_job(jcr, jobid, deleted, sendit, ctx)
+#define db_list_fileevents_for_job(jcr, mdb, jobid, etype, sendit, ctx, type) \
+ mdb->bdb_list_fileevents_for_job(jcr, jobid, etype, sendit, ctx, type)
#define db_list_media_records(jcr, mdb, mdbr, sendit, ctx, type) \
mdb->bdb_list_media_records(jcr, mdbr, sendit, ctx, type)
#define db_list_jobmedia_records(jcr, mdb, JobId, volume, sendit, ctx, type) \
bdb_unlock();
}
+/* List all file records from a job
+ * "deleted" values are described just below
+ */
+void BDB::bdb_list_fileevents_for_job(JCR *jcr, JobId_t jobid, char etype, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
+{
+ char ed1[50];
+ POOL_MEM f, fields;
+ const char *concat="Path.Path||F.Filename";
+
+ bdb_lock();
+ /* Get optional filters for the SQL query */
+ const char *where = get_acls(DB_ACL_BIT(DB_ACL_JOB) |
+ DB_ACL_BIT(DB_ACL_CLIENT) |
+ DB_ACL_BIT(DB_ACL_FILESET), true);
+
+ const char *join = *where ? get_acl_join_filter(DB_ACL_BIT(DB_ACL_JOB) |
+ DB_ACL_BIT(DB_ACL_CLIENT) |
+ DB_ACL_BIT(DB_ACL_FILESET)) : "";
+
+ if (etype) {
+ Mmsg(f, " AND FileEvents.Type = '%c' ", etype);
+ }
+
+ /*
+ * MySQL is different with no || operator
+ */
+ if (bdb_get_type_index() == SQL_TYPE_MYSQL) {
+ concat = " CONCAT(Path.Path,F.Filename) ";
+ }
+
+ switch (type) {
+ case JSON_LIST:
+ Mmsg(fields, "JobId, %s AS Filename, Type, Severity, Description, Source", concat);
+ break;
+ case VERT_LIST:
+ Mmsg(fields, "JobId, SourceJobId, %s AS Filename, Type, Severity, Description, Source", concat);
+ break;
+ case HORZ_LIST:
+ Mmsg(fields, "JobId, %s AS Filename, Description, Source", concat);
+ break;
+ default:
+ goto bail_out;
+ }
+
+ Mmsg(cmd, "SELECT DISTINCT %s "
+ "FROM (SELECT PathId, Filename, File.JobId, FileEvents.SourceJobId, FileEvents.Type, FileEvents.Description, FileEvents.Source, FileEvents.Severity FROM File "
+ "JOIN FileEvents ON (File.JobId = FileEvents.JobId AND File.FileIndex = FileEvents.FileIndex) "
+ "WHERE File.JobId=%s %s "
+ "UNION ALL "
+ "SELECT PathId, Filename, BaseFiles.JobId, FileEvents.SourceJobId, FileEvents.Type, FileEvents.Description, FileEvents.Source, FileEvents.Severity "
+ "FROM BaseFiles JOIN File ON (BaseFiles.FileId = File.FileId) "
+ "JOIN FileEvents ON (File.JobId = FileEvents.JobId AND File.FileIndex = FileEvents.FileIndex) "
+ "WHERE BaseFiles.JobId = %s %s "
+ ") AS F JOIN Path ON (Path.PathId=F.PathId) %s %s",
+ fields.c_str(),
+ edit_int64(jobid, ed1), f.c_str(), ed1, f.c_str(), join, where);
+
+ Dmsg1(DT_SQL|50, "q=%s\n", cmd);
+
+ if (!QueryDB(jcr, cmd)) {
+ goto bail_out;
+ }
+
+ // TODO: Display
+ list_result(jcr, this, "fileevents", sendit, ctx, type);
+
+bail_out:
+ sql_free_result();
+ bdb_unlock();
+}
+
void BDB::bdb_list_base_files_for_job(JCR *jcr, JobId_t jobid, DB_LIST_HANDLER *sendit, void *ctx)
{
char ed1[50];
type = hash_get_type(strlen((char *)lst[0]));
if (!type) {
- Mmsg(errmsg, "[DE0006] Unable to detect the checksum type for JobIds %s\n", jobids);
+ Mmsg(errmsg, "[DE0006] Unable to find a valid checksum database for JobIds %s\n", jobids);
return -1;
}
/* We keep track of the infected files in the FileEvents table */
Mmsg(q, "INSERT INTO FileEvents (SourceJobId, JobId, FileId, Type, Description, Severity, Source) "
- "SELECT JobId, JobId, FileId, 'M', 'Malware found', 100, '%s' FROM File JOIN Malware%s USING (MD5) "
- "WHERE JobId IN (%s)", source_esc.c_str(), type, jobids);
+ "SELECT %ld, JobId, FileId, 'M', 'Malware found', 100, '%s' FROM File JOIN Malware%s USING (MD5) "
+ "WHERE JobId IN (%s)", jcr->JobId, source_esc.c_str(), type, jobids);
if (!db_sql_query(jcr->db, q.c_str(), NULL, NULL)) {
Mmsg(errmsg, "[DE0008] SQL Error %s\n", jcr->db->errmsg);
* list joblog pattern=xxx jobid=<nn>
* list joblog pattern=xxx jobid=<nn>
* list joblog job=name
- * list files [type=<deleted|all>] jobid=<nn> - list files saved for job nn
- * list files [type=<deleted|all>] job=name
+ * list files [type=<deleted|all|malware>] jobid=<nn> - list files saved for job nn
+ * list files [type=<deleted|all|malware>] job=name
* list pools - list pool records
* list jobtotals - list totals for all jobs
* list media - list media for given pool (deprecated)
* starttime=<time> endtime=<time>
* limit=<int> offset=<int> order=<Asc|desc> alljobs
* emailid=<str>
- *
* Note: keyword "long" is before the first command on the command
* line results in doing a llist (long listing).
*/
/* List FILES */
} else if (strcasecmp(ua->argk[i], NT_("files")) == 0) {
int deleted = 0; /* see only backed up files */
+ char malware = 0; /* List malware detected */
for (j=i+1; j<ua->argc; j++) {
if (strcasecmp(ua->argk[j], NT_("ujobid")) == 0 && ua->argv[j]) {
bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH);
deleted = 1;
} else if (strcasecmp(ua->argv[j], NT_("all")) == 0) {
deleted = -1;
+ } else if (strcasecmp(ua->argv[j], NT_("malware")) == 0) {
+ malware = 'M';
}
continue; /* Type should be before the jobid... */
} else {
continue;
}
if (jobid > 0) {
- db_list_files_for_job(ua->jcr, ua->db, jobid, deleted, prtit, ua);
+ if (malware) {
+ db_list_fileevents_for_job(ua->jcr, ua->db, jobid, malware, prtit, ua, llist);
+
+ } else {
+ db_list_files_for_job(ua->jcr, ua->db, jobid, deleted, prtit, ua);
+ }
}
}