]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/status.h
Fix status alignment output reported by Wanderlei Huttel
[bacula/bacula] / bacula / src / lib / status.h
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2016 Kern Sibbald
5
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.
8
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.
13
14    This notice must be preserved when any source code is 
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
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.
24  *
25  *     Kern Sibbald, March MMVII
26  *
27  */
28
29 #ifndef __STATUS_H_
30 #define __STATUS_H_
31
32 /*
33  * Packet to send to output_status()
34  */
35 class STATUS_PKT {
36 public:
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 */
42
43   /* Methods */
44   STATUS_PKT() { memset(this, 0, sizeof(STATUS_PKT)); };
45   ~STATUS_PKT() { };
46 };
47
48 extern void output_status(STATUS_PKT *sp);
49
50 /*
51  * Send to bsock (Director or Console)
52  */
53 static void sendit(const char *msg, int len, STATUS_PKT *sp)
54 {
55    if (sp->bs) {
56       BSOCK *user = sp->bs;
57       user->msg = check_pool_memory_size(user->msg, len+1);
58       memcpy(user->msg, msg, len+1);
59       user->msglen = len+1;
60       user->send();
61    } else {
62       sp->callback(msg, len, sp->context);
63    }
64 }
65
66 #ifndef STATUS_FUNCTIONS
67 #define STATUS_FUNCTIONS
68
69 /* common to SD/FD */
70 static void list_terminated_jobs(STATUS_PKT *sp)
71 {
72    char dt[MAX_TIME_LENGTH], b1[30], b2[30];
73    char level[10];
74    struct s_last_job *je;
75    const char *msg;
76
77    msg =  _("\nTerminated Jobs:\n");
78    if (!sp->api) sendit(msg, strlen(msg), sp);
79    if (last_jobs->size() == 0) {
80       if (!sp->api) sendit("====\n", 5, sp);
81       return;
82    }
83    lock_last_jobs_list();
84    msg =  _(" JobId  Level      Files    Bytes   Status   Finished        Name \n");
85    if (!sp->api) sendit(msg, strlen(msg), sp);
86    msg =  _("===================================================================\n");
87    if (!sp->api) sendit(msg, strlen(msg), sp);
88    foreach_dlist(je, last_jobs) {
89       char JobName[MAX_NAME_LENGTH];
90       const char *termstat;
91       char buf[1000];
92
93       bstrftime_nc(dt, sizeof(dt), je->end_time);
94       switch (je->JobType) {
95       case JT_ADMIN:
96          bstrncpy(level, "Admin", sizeof(level));
97       case JT_RESTORE:
98          bstrncpy(level, "Restore", sizeof(level));
99          break;
100       default:
101          bstrncpy(level, job_level_to_str(je->JobLevel), sizeof(level));
102          level[4] = 0;
103          break;
104       }
105       switch (je->JobStatus) {
106       case JS_Created:
107          termstat = _("Created");
108          break;
109       case JS_FatalError:
110       case JS_ErrorTerminated:
111          termstat = _("Error");
112          break;
113       case JS_Differences:
114          termstat = _("Diffs");
115          break;
116       case JS_Canceled:
117          termstat = _("Cancel");
118          break;
119       case JS_Terminated:
120          termstat = _("OK");
121          break;
122       case JS_Warnings:
123          termstat = _("OK -- with warnings");
124          break;
125       case JS_Incomplete:
126          termstat = _("Incomplete");
127          break;
128       default:
129          termstat = _("Other");
130          break;
131       }
132       bstrncpy(JobName, je->Job, sizeof(JobName));
133       /* There are three periods after the Job name */
134       char *p;
135       for (int i=0; i<3; i++) {
136          if ((p=strrchr(JobName, '.')) != NULL) {
137             *p = 0;
138          }
139       }
140       if (sp->api == 1) {
141          bsnprintf(buf, sizeof(buf), _("%6d\t%-7s\t%8s\t%10s\t%-7s\t%-8s\t%s\n"),
142             je->JobId,
143             level,
144             edit_uint64_with_commas(je->JobFiles, b1),
145             edit_uint64_with_suffix(je->JobBytes, b2),
146             termstat,
147             dt, JobName);
148       } else {
149          bsnprintf(buf, sizeof(buf), _("%6d  %-7s %8s %10s  %-7s  %-8s %s\n"),
150             je->JobId,
151             level,
152             edit_uint64_with_commas(je->JobFiles, b1),
153             edit_uint64_with_suffix(je->JobBytes, b2),
154             termstat,
155             dt, JobName);
156       }
157       sendit(buf, strlen(buf), sp);
158    }
159    unlock_last_jobs_list();
160    if (!sp->api) {
161       sendit("====\n", 5, sp);
162    }
163 }
164
165 #if defined(HAVE_WIN32)
166 int bacstat = 0;
167
168 #ifdef FILE_DAEMON
169 # define BAC_COMPONENT "Client"
170 #else
171 # define BAC_COMPONENT "Storage"
172 #endif
173
174 /* Return a one line status for the tray monitor */
175 char *bac_status(char *buf, int buf_len)
176 {
177    JCR *njcr;
178    const char *termstat = _("Bacula " BAC_COMPONENT ": Idle");
179    struct s_last_job *job;
180    int stat = 0;                      /* Idle */
181
182    if (!last_jobs) {
183       goto done;
184    }
185    Dmsg0(1000, "Begin bac_status jcr loop.\n");
186    foreach_jcr(njcr) {
187       if (njcr->JobId != 0) {
188          stat = JS_Running;
189          termstat = _("Bacula " BAC_COMPONENT ": Running");
190          break;
191       }
192    }
193    endeach_jcr(njcr);
194
195    if (stat != 0) {
196       goto done;
197    }
198    if (last_jobs->size() > 0) {
199       job = (struct s_last_job *)last_jobs->last();
200       stat = job->JobStatus;
201       switch (job->JobStatus) {
202       case JS_Canceled:
203          termstat = _("Bacula " BAC_COMPONENT ": Last Job Canceled");
204          break;
205       case JS_ErrorTerminated:
206       case JS_FatalError:
207          termstat = _("Bacula " BAC_COMPONENT ": Last Job Failed");
208          break;
209       default:
210          if (job->Errors) {
211             termstat = _("Bacula " BAC_COMPONENT ": Last Job had Warnings");
212          }
213          break;
214       }
215    }
216    Dmsg0(1000, "End bac_status jcr loop.\n");
217 done:
218    bacstat = stat;
219    if (buf) {
220       bstrncpy(buf, termstat, buf_len);
221    }
222    return buf;
223 }
224
225 #endif /* HAVE_WIN32 */
226
227 #endif  /* ! STATUS_FUNCTIONS */
228
229 #endif