+ len = Mmsg(msg, "%sOPENED %sTAPE %sLABEL %sMALLOC %sAPPEND %sREAD %sEOT %sWEOT %sEOF %sNEXTVOL %sSHORT %sMOUNTED\n",
+ dev->is_open() ? "" : "!",
+ dev->is_tape() ? "" : "!",
+ dev->is_labeled() ? "" : "!",
+ dev->state & ST_MALLOC ? "" : "!",
+ dev->can_append() ? "" : "!",
+ dev->can_read() ? "" : "!",
+ dev->at_eot() ? "" : "!",
+ dev->state & ST_WEOT ? "" : "!",
+ dev->at_eof() ? "" : "!",
+ dev->state & ST_NEXTVOL ? "" : "!",
+ dev->state & ST_SHORT ? "" : "!",
+ dev->state & ST_MOUNTED ? "" : "!");
+ sendit(msg, len, sp);
+
+ len = Mmsg(msg, _("num_writers=%d reserved=%d block=%d\n\n"), dev->num_writers,
+ dev->num_reserved(), dev->blocked());
+ sendit(msg, len, sp);
+
+ len = Mmsg(msg, _("Device parameters:\n"));
+ sendit(msg, len, sp);
+
+ len = Mmsg(msg, _("Archive name: %s Device name: %s\n"), dev->archive_name(),
+ dev->name());
+ sendit(msg, len, sp);
+
+ len = Mmsg(msg, _("File=%u block=%u\n"), dev->file, dev->block_num);
+ sendit(msg, len, sp);
+
+ len = Mmsg(msg, _("Min block=%u Max block=%u\n"), dev->min_block_size, dev->max_block_size);
+ sendit(msg, len, sp);
+}
+
+static void list_running_jobs(STATUS_PKT *sp)
+{
+ bool found = false;
+ int bps, sec;
+ JCR *jcr;
+ DCR *dcr, *rdcr;
+ char JobName[MAX_NAME_LENGTH];
+ char b1[30], b2[30], b3[30];
+ int len;
+ POOL_MEM msg(PM_MESSAGE);
+
+ len = Mmsg(msg, _("\nRunning Jobs:\n"));
+ if (!sp->api) sendit(msg, len, sp);
+
+ foreach_jcr(jcr) {
+ if (jcr->JobStatus == JS_WaitFD) {
+ len = Mmsg(msg, _("%s Job %s waiting for Client connection.\n"),
+ job_type_to_str(jcr->get_JobType()), jcr->Job);
+ sendit(msg, len, sp);
+ }
+ dcr = jcr->dcr;
+ rdcr = jcr->read_dcr;
+ if ((dcr && dcr->device) || (rdcr && rdcr->device)) {
+ bstrncpy(JobName, jcr->Job, sizeof(JobName));
+ /* There are three periods after the Job name */
+ char *p;
+ for (int i=0; i<3; i++) {
+ if ((p=strrchr(JobName, '.')) != NULL) {
+ *p = 0;
+ }
+ }
+ if (rdcr && rdcr->device) {
+ len = Mmsg(msg, _("Reading: %s %s job %s JobId=%d Volume=\"%s\"\n"
+ " pool=\"%s\" device=%s\n"),
+ job_level_to_str(jcr->get_JobLevel()),
+ job_type_to_str(jcr->get_JobType()),
+ JobName,
+ jcr->JobId,
+ rdcr->VolumeName,
+ rdcr->pool_name,
+ rdcr->dev?rdcr->dev->print_name():
+ rdcr->device->device_name);
+ sendit(msg, len, sp);
+ }
+ if (dcr && dcr->device) {
+ len = Mmsg(msg, _("Writing: %s %s job %s JobId=%d Volume=\"%s\"\n"
+ " pool=\"%s\" device=%s\n"),
+ job_level_to_str(jcr->get_JobLevel()),
+ job_type_to_str(jcr->get_JobType()),
+ JobName,
+ jcr->JobId,
+ dcr->VolumeName,
+ dcr->pool_name,
+ dcr->dev?dcr->dev->print_name():
+ dcr->device->device_name);
+ sendit(msg, len, sp);
+ len= Mmsg(msg, _(" spooling=%d despooling=%d despool_wait=%d\n"),
+ dcr->spooling, dcr->despooling, dcr->despool_wait);
+ sendit(msg, len, sp);
+ }
+ sec = time(NULL) - jcr->run_time;
+ if (sec <= 0) {
+ sec = 1;
+ }
+ bps = jcr->JobBytes / sec;
+ len = Mmsg(msg, _(" Files=%s Bytes=%s Bytes/sec=%s\n"),
+ edit_uint64_with_commas(jcr->JobFiles, b1),
+ edit_uint64_with_commas(jcr->JobBytes, b2),
+ edit_uint64_with_commas(bps, b3));
+ sendit(msg, len, sp);
+ found = true;
+#ifdef DEBUG
+ if (jcr->file_bsock) {
+ len = Mmsg(msg, _(" FDReadSeqNo=%s in_msg=%u out_msg=%d fd=%d\n"),
+ edit_uint64_with_commas(jcr->file_bsock->read_seqno, b1),
+ jcr->file_bsock->in_msg_no, jcr->file_bsock->out_msg_no,
+ jcr->file_bsock->m_fd);
+ sendit(msg, len, sp);
+ } else {
+ len = Mmsg(msg, _(" FDSocket closed\n"));
+ sendit(msg, len, sp);
+ }
+#endif
+ }
+ }
+ endeach_jcr(jcr);
+
+ if (!found) {
+ len = Mmsg(msg, _("No Jobs running.\n"));
+ if (!sp->api) sendit(msg, len, sp);
+ }
+ if (!sp->api) sendit("====\n", 5, sp);
+}
+
+static void list_jobs_waiting_on_reservation(STATUS_PKT *sp)
+{
+ JCR *jcr;
+ POOL_MEM msg(PM_MESSAGE);
+ int len;
+
+ len = Mmsg(msg, _("\nJobs waiting to reserve a drive:\n"));
+ if (!sp->api) sendit(msg, len, sp);
+
+ foreach_jcr(jcr) {
+ if (!jcr->reserve_msgs) {
+ continue;
+ }
+ send_drive_reserve_messages(jcr, sendit, sp);
+ }
+ endeach_jcr(jcr);
+
+ if (!sp->api) sendit("====\n", 5, sp);