2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Status packet definition that is used in both the SD and FD. It
21 * permits Win32 to call output_status() and get the output back
22 * at the callback address line by line, and for Linux code,
23 * the output can be sent directly to a BSOCK.
25 * Kern Sibbald, March MMVII
33 * Packet to send to output_status()
37 BSOCK *bs; /* used on Unix machines */
38 void *context; /* Win32 */
39 void (*callback)(const char *msg, int len, void *context); /* Win32 */
40 char api_opts[MAX_NAME_LENGTH];
41 int api; /* set if we want API output, with api level */
44 STATUS_PKT() { memset(this, 0, sizeof(STATUS_PKT)); };
48 extern void output_status(STATUS_PKT *sp);
51 * Send to bsock (Director or Console)
53 static void sendit(const char *msg, int len, STATUS_PKT *sp)
57 user->msg = check_pool_memory_size(user->msg, len+1);
58 memcpy(user->msg, msg, len+1);
62 sp->callback(msg, len, sp->context);
66 #ifndef STATUS_FUNCTIONS
67 #define STATUS_FUNCTIONS
70 static void list_terminated_jobs(STATUS_PKT *sp)
72 OutputWriter ow(sp->api_opts);
73 char dt[MAX_TIME_LENGTH], b1[30], b2[30];
75 struct s_last_job *je;
79 msg = _("\nTerminated Jobs:\n");
80 if (!sp->api) sendit(msg, strlen(msg), sp);
81 if (last_jobs->size() == 0) {
82 if (!sp->api) sendit("====\n", 5, sp);
85 lock_last_jobs_list();
86 msg = _(" JobId Level Files Bytes Status Finished Name \n");
87 if (!sp->api) sendit(msg, strlen(msg), sp);
88 msg = _("===================================================================\n");
89 if (!sp->api) sendit(msg, strlen(msg), sp);
91 p = ow.start_group("terminated");
92 sendit(p, strlen(p), sp);
94 foreach_dlist(je, last_jobs) {
95 char JobName[MAX_NAME_LENGTH];
99 bstrftime_nc(dt, sizeof(dt), je->end_time);
100 switch (je->JobType) {
102 bstrncpy(level, "Admn", sizeof(level));
105 bstrncpy(level, "Rest", sizeof(level));
108 bstrncpy(level, job_level_to_str(je->JobLevel), sizeof(level));
112 switch (je->JobStatus) {
114 termstat = _("Created");
117 case JS_ErrorTerminated:
118 termstat = _("Error");
121 termstat = _("Diffs");
124 termstat = _("Cancel");
130 termstat = _("OK -- with warnings");
133 termstat = _("Incomplete");
136 termstat = _("Other");
139 bstrncpy(JobName, je->Job, sizeof(JobName));
140 /* There are three periods after the Job name */
142 for (int i=0; i<3; i++) {
143 if ((p=strrchr(JobName, '.')) != NULL) {
148 bsnprintf(buf, sizeof(buf), _("%6d\t%-7s\t%8s\t%10s\t%-7s\t%-8s\t%s\n"),
151 edit_uint64_with_commas(je->JobFiles, b1),
152 edit_uint64_with_suffix(je->JobBytes, b2),
156 } else if (sp->api > 1) {
157 p = ow.get_output(OT_CLEAR,
159 OT_INT, "jobid", je->JobId,
160 OT_JOBLEVEL,"level", je->JobLevel,
161 OT_JOBTYPE, "type", je->JobType,
162 OT_JOBSTATUS,"status", je->JobStatus,
163 OT_STRING, "status_desc",termstat,
164 OT_SIZE, "jobbytes", je->JobBytes,
165 OT_INT32, "jobfiles", je->JobFiles,
166 OT_STRING, "job", je->Job,
167 OT_STRING, "name", JobName,
168 OT_UTIME, "starttime", je->start_time,
169 OT_UTIME, "endtime", je->end_time,
170 OT_INT, "errors", je->Errors,
173 sendit(p, strlen(p), sp);
177 bsnprintf(buf, sizeof(buf), _("%6d %-7s %8s %10s %-7s %-8s %s\n"),
180 edit_uint64_with_commas(je->JobFiles, b1),
181 edit_uint64_with_suffix(je->JobBytes, b2),
185 sendit(buf, strlen(buf), sp);
187 unlock_last_jobs_list();
189 sendit("====\n", 5, sp);
190 } else if (sp->api > 1) {
191 p = ow.end_group(false);
192 sendit(p, strlen(p), sp);
196 #if defined(HAVE_WIN32)
200 # define BAC_COMPONENT "Client"
202 # define BAC_COMPONENT "Storage"
205 /* Return a one line status for the tray monitor */
206 char *bac_status(char *buf, int buf_len)
209 const char *termstat = _("Bacula " BAC_COMPONENT ": Idle");
210 struct s_last_job *job;
211 int stat = 0; /* Idle */
216 Dmsg0(1000, "Begin bac_status jcr loop.\n");
218 if (njcr->JobId != 0) {
220 termstat = _("Bacula " BAC_COMPONENT ": Running");
229 if (last_jobs->size() > 0) {
230 job = (struct s_last_job *)last_jobs->last();
231 stat = job->JobStatus;
232 switch (job->JobStatus) {
234 termstat = _("Bacula " BAC_COMPONENT ": Last Job Canceled");
236 case JS_ErrorTerminated:
238 termstat = _("Bacula " BAC_COMPONENT ": Last Job Failed");
242 termstat = _("Bacula " BAC_COMPONENT ": Last Job had Warnings");
247 Dmsg0(1000, "End bac_status jcr loop.\n");
251 bstrncpy(buf, termstat, buf_len);
256 #endif /* HAVE_WIN32 */
258 #endif /* ! STATUS_FUNCTIONS */