]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/status.h
59271f7f871064c9be349db2a2197fa7191dedbe
[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       case JT_RESTORE:
97          bstrncpy(level, "    ", sizeof(level));
98          break;
99       default:
100          bstrncpy(level, job_level_to_str(je->JobLevel), sizeof(level));
101          level[4] = 0;
102          break;
103       }
104       switch (je->JobStatus) {
105       case JS_Created:
106          termstat = _("Created");
107          break;
108       case JS_FatalError:
109       case JS_ErrorTerminated:
110          termstat = _("Error");
111          break;
112       case JS_Differences:
113          termstat = _("Diffs");
114          break;
115       case JS_Canceled:
116          termstat = _("Cancel");
117          break;
118       case JS_Terminated:
119          termstat = _("OK");
120          break;
121       case JS_Warnings:
122          termstat = _("OK -- with warnings");
123          break;
124       case JS_Incomplete:
125          termstat = _("Incomplete");
126          break;
127       default:
128          termstat = _("Other");
129          break;
130       }
131       bstrncpy(JobName, je->Job, sizeof(JobName));
132       /* There are three periods after the Job name */
133       char *p;
134       for (int i=0; i<3; i++) {
135          if ((p=strrchr(JobName, '.')) != NULL) {
136             *p = 0;
137          }
138       }
139       if (sp->api == 1) {
140          bsnprintf(buf, sizeof(buf), _("%6d\t%-6s\t%8s\t%10s\t%-7s\t%-8s\t%s\n"),
141             je->JobId,
142             level,
143             edit_uint64_with_commas(je->JobFiles, b1),
144             edit_uint64_with_suffix(je->JobBytes, b2),
145             termstat,
146             dt, JobName);
147       } else {
148          bsnprintf(buf, sizeof(buf), _("%6d  %-6s %8s %10s  %-7s  %-8s %s\n"),
149             je->JobId,
150             level,
151             edit_uint64_with_commas(je->JobFiles, b1),
152             edit_uint64_with_suffix(je->JobBytes, b2),
153             termstat,
154             dt, JobName);
155       }
156       sendit(buf, strlen(buf), sp);
157    }
158    unlock_last_jobs_list();
159    if (!sp->api) {
160       sendit("====\n", 5, sp);
161    }
162 }
163
164 #if defined(HAVE_WIN32)
165 int bacstat = 0;
166
167 #ifdef FILE_DAEMON
168 # define BAC_COMPONENT "Client"
169 #else
170 # define BAC_COMPONENT "Storage"
171 #endif
172
173 /* Return a one line status for the tray monitor */
174 char *bac_status(char *buf, int buf_len)
175 {
176    JCR *njcr;
177    const char *termstat = _("Bacula " BAC_COMPONENT ": Idle");
178    struct s_last_job *job;
179    int stat = 0;                      /* Idle */
180
181    if (!last_jobs) {
182       goto done;
183    }
184    Dmsg0(1000, "Begin bac_status jcr loop.\n");
185    foreach_jcr(njcr) {
186       if (njcr->JobId != 0) {
187          stat = JS_Running;
188          termstat = _("Bacula " BAC_COMPONENT ": Running");
189          break;
190       }
191    }
192    endeach_jcr(njcr);
193
194    if (stat != 0) {
195       goto done;
196    }
197    if (last_jobs->size() > 0) {
198       job = (struct s_last_job *)last_jobs->last();
199       stat = job->JobStatus;
200       switch (job->JobStatus) {
201       case JS_Canceled:
202          termstat = _("Bacula " BAC_COMPONENT ": Last Job Canceled");
203          break;
204       case JS_ErrorTerminated:
205       case JS_FatalError:
206          termstat = _("Bacula " BAC_COMPONENT ": Last Job Failed");
207          break;
208       default:
209          if (job->Errors) {
210             termstat = _("Bacula " BAC_COMPONENT ": Last Job had Warnings");
211          }
212          break;
213       }
214    }
215    Dmsg0(1000, "End bac_status jcr loop.\n");
216 done:
217    bacstat = stat;
218    if (buf) {
219       bstrncpy(buf, termstat, buf_len);
220    }
221    return buf;
222 }
223
224 #endif /* HAVE_WIN32 */
225
226 #endif  /* ! STATUS_FUNCTIONS */
227
228 #endif