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_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, 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);
void bdb_list_joblog_records(JCR *jcr, JobId_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
int bdb_list_sql_query(JCR *jcr, const char *query, DB_LIST_HANDLER *sendit, void *ctx, int verbose, e_list_type type);
mdb->bdb_list_files_for_job(jcr, jobid, deleted, sendit, ctx)
#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, sendit, ctx, type) \
- mdb->bdb_list_jobmedia_records(jcr, JobId, sendit, ctx, type)
+#define db_list_jobmedia_records(jcr, mdb, JobId, volume, sendit, ctx, type) \
+ mdb->bdb_list_jobmedia_records(jcr, JobId, volume, sendit, ctx, type)
#define db_list_filemedia_records(jcr, mdb, JobId, FI, sendit, ctx, type) \
mdb->bdb_list_filemedia_records(jcr, JobId, FI, sendit, ctx, type)
#define db_list_joblog_records(jcr, mdb, JobId, sendit, ctx, type) \
bdb_unlock();
}
-void BDB::bdb_list_jobmedia_records(JCR *jcr, uint32_t JobId,
+void BDB::bdb_list_jobmedia_records(JCR *jcr, uint32_t JobId, char *volume,
DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
{
- char ed1[50];
-
+ POOL_MEM where2;
bdb_lock();
/* Get some extra SQL parameters if needed */
const char *where = get_acls(DB_ACL_BIT(DB_ACL_JOB) |
DB_ACL_BIT(DB_ACL_FILESET) |
- DB_ACL_BIT(DB_ACL_CLIENT), (JobId == 0));
+ DB_ACL_BIT(DB_ACL_POOL) |
+ DB_ACL_BIT(DB_ACL_CLIENT), (JobId == 0 || volume != NULL));
const char *join = *where ? get_acl_join_filter(DB_ACL_BIT(DB_ACL_JOB) |
DB_ACL_BIT(DB_ACL_FILESET) |
+ DB_ACL_BIT(DB_ACL_POOL) |
DB_ACL_BIT(DB_ACL_CLIENT)) : "";
+ if (JobId) {
+ Mmsg(where2, " WHERE JobMedia.JobId=%lu ", JobId);
+ }
+
+ if (volume) {
+ POOL_MEM tmp, tmp2;
+ int len = strlen(volume);
+ tmp.check_size(len*2+1);
+ db_escape_string(jcr, this, tmp.c_str(), volume, len);
+ Mmsg(tmp2, " %s Media.VolumeName = '%s' ", JobId == 0 ?"WHERE": "AND", tmp.c_str());
+ pm_strcat(where2, tmp2.c_str());
+ }
+
if (type == VERT_LIST || type == JSON_LIST) {
- if (JobId > 0) { /* do by JobId */
- Mmsg(cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName,"
- "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock,"
- "JobMedia.EndBlock "
- "FROM JobMedia JOIN Media USING (MediaId) %s "
- "WHERE JobMedia.JobId=%s %s",
- join,
- edit_int64(JobId, ed1),
- where);
- } else {
- Mmsg(cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName,"
- "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock,"
- "JobMedia.EndBlock "
- "FROM JobMedia JOIN Media USING (MediaId) %s %s",
- join,
- where);
- }
+ Mmsg(cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName,"
+ "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock,"
+ "JobMedia.EndBlock "
+ "FROM JobMedia JOIN Media USING (MediaId) %s "
+ "%s %s ORDER BY JobMediaId ASC",
+ join,
+ where2.c_str(),
+ where);
} else {
- if (JobId > 0) { /* do by JobId */
- Mmsg(cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex "
- "FROM JobMedia JOIN Media USING (MediaId) %s WHERE "
- "JobMedia.JobId=%s %s",
- join,
- edit_int64(JobId, ed1),
- where);
- } else {
- Mmsg(cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex "
- "FROM JobMedia JOIN Media USING (MediaId) %s %s",
- join,
- where);
- }
+ Mmsg(cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex "
+ "FROM JobMedia JOIN Media USING (MediaId) %s %s %s ORDER BY JobMediaId ASC",
+ join,
+ where2.c_str(),
+ where);
}
Dmsg1(DT_SQL|50, "q=%s\n", cmd);
NT_("jobs [client=<cli>] [jobid=<nn>] [ujobid=<name>] [job=<name>] [tag=<name>] [joberrors] [jobstatus=<s>] [level=<l>] [jobtype=<t>] [days=<n>] [hours=<n>] [limit=<n>] [order=<asc|desc>]|\n"
"\tjobtotals | pools | volume | media <pool=pool-name> | files [type=<deleted|all>] jobid=<nn> | copies jobid=<nn> |\n"
"\tjoblog jobid=<nn> | pluginrestoreconf jobid=<nn> restoreobjectid=<nn> | snapshot | \n"
- "\tfilemedia jobid=<nn> fileindex=<mm> | clients\n"
+ "\tfilemedia jobid=<nn> fileindex=<mm> | clients | jobmedia [jobid=<nn> volume=<s>] |\n"
"\tevents [type=<str> | limit=<int> | order=<asc|desc> | days=<int> | start=<time-specification> | end=<time-specification> |\n"
"\t\t source=<str> | code=<str> | type=<str> ]\n"
"\tobjects [jobid=<jobid> client=<cli> type=<str> | category=<str> | status=<S> | limit=<int> | order=<asc|desc> ]\n"
const char *p;
const char *accept = ":.-_";
+ if (!name) {
+ if (ua) {
+ ua->error_msg(_("No volume specified.\n"));
+ }
+ return 0;
+ }
+
/* Restrict the characters permitted in the Volume name */
for (p=name; *p; p++) {
if (B_ISALPHA(*p) || B_ISDIGIT(*p) || strchr(accept, (int)(*p))) {
/* List JOBMEDIA */
} else if (strcasecmp(ua->argk[i], NT_("jobmedia")) == 0) {
- bool done = false;
+ char *volume = NULL;
+ jobid = 0;
+
for (j=i+1; j<ua->argc; j++) {
- if (strcasecmp(ua->argk[j], NT_("ujobid")) == 0 && ua->argv[j]) {
+ if (strcasecmp(ua->argk[j], NT_("ujobid")) == 0 && ua->argv[j] && is_name_valid(ua->argv[j], NULL)) {
bstrncpy(jr.Job, ua->argv[j], MAX_NAME_LENGTH);
jr.JobId = 0;
db_get_job_record(ua->jcr, ua->db, &jr);
jobid = jr.JobId;
+
} else if (strcasecmp(ua->argk[j], NT_("jobid")) == 0 && ua->argv[j]) {
jobid = str_to_int64(ua->argv[j]);
+
+ } else if (strcasecmp(ua->argk[j], NT_("volume")) == 0 &&
+ ua->argv[j] && is_volume_name_legal(ua, ua->argv[j])) {
+ volume = ua->argv[j];
+
} else {
continue;
}
- db_list_jobmedia_records(ua->jcr, ua->db, jobid, prtit, ua, llist);
- done = true;
- }
- if (!done) {
- /* List for all jobs (jobid=0) */
- db_list_jobmedia_records(ua->jcr, ua->db, 0, prtit, ua, llist);
}
+ db_list_jobmedia_records(ua->jcr, ua->db, jobid, volume, prtit, ua, llist);
+ return 1;
+
/* list filemedia */
} else if (strcasecmp(ua->argk[i], NT_("filemedia")) == 0) {
int32_t findex=0;
return this->watchDirRecursive(folder);
}
-POOLMEM *FolderWatcher::watchDirRecursive(const char *dir)
+char *FolderWatcher::watchDirRecursive(const char *dir, POOLMEM **err_msg)
{
DIR *dirReader = NULL;
struct dirent *dirFile = NULL;
const char *separator = NULL;
POOLMEM *subdirPath = NULL;
- char *err_msg = NULL;
+ pm_strcpy(err_msg, "");
uint32_t mask = IN_CLOSE | IN_ATTRIB | IN_MOVE
| IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_OPEN
int wd = inotify_add_watch(_fd, dir, mask);
if (wd < 0) {
- err_msg = get_pool_memory(PM_EMSG);
-
switch (errno) {
case EACCES:
Mmsg(err_msg, "Could not watch Directory. Access Denied for: %s", dir);
} else if (closeNoWriteFileEvent) {
_openedFiles.erase(event->wd);
} else if (createEvent && isDir) {
- this->watchDirRecursive(fpath);
+ POOLMEM *tmp = this->watchDirRecursive(fpath);
+ free_and_null_pool_memory(tmp);
} else if (movedToEvent) {
_changeHandler->onChange(fpath);
} else if ((modifyEvent || attribsChangeEvent)