1 /*
2    Bacula(R) - The Network Backup Solution
3 
4    Copyright (C) 2000-2020 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  * Common definitions and utility functions for Inteos plugins.
21  * Functions defines a common framework used in our utilities and plugins.
22  *
23  * Author: Radosław Korzeniewski, MMXIX
24  * radoslaw@korzeniewski.net, radekk@inteos.pl
25  * Inteos Sp. z o.o. http://www.inteos.pl/
26  */
27 
28 #include "pluglib.h"
29 
30 /* Events that are passed to plugin
31 typedef enum {
32   bEventJobStart                        = 1,
33   bEventJobEnd                          = 2,
34   bEventStartBackupJob                  = 3,
35   bEventEndBackupJob                    = 4,
36   bEventStartRestoreJob                 = 5,
37   bEventEndRestoreJob                   = 6,
38   bEventStartVerifyJob                  = 7,
39   bEventEndVerifyJob                    = 8,
40   bEventBackupCommand                   = 9,
41   bEventRestoreCommand                  = 10,
42   bEventEstimateCommand                 = 11,
43   bEventLevel                           = 12,
44   bEventSince                           = 13,
45   bEventCancelCommand                   = 14,
46   bEventVssBackupAddComponents          = 15,
47   bEventVssRestoreLoadComponentMetadata = 16,
48   bEventVssRestoreSetComponentsSelected = 17,
49   bEventRestoreObject                   = 18,
50   bEventEndFileSet                      = 19,
51   bEventPluginCommand                   = 20,
52   bEventVssBeforeCloseRestore           = 21,
53   bEventVssPrepareSnapshot              = 22,
54   bEventOptionPlugin                    = 23,
55   bEventHandleBackupFile                = 24,
56   bEventComponentInfo                   = 25
57 } bEventType;
58 */
59 
eventtype2str(bEvent * event)60 const char *eventtype2str(bEvent *event){
61    switch (event->eventType){
62       case bEventJobStart:
63          return "bEventJobStart";
64       case bEventJobEnd:
65          return "bEventJobEnd";
66       case bEventStartBackupJob:
67          return "bEventStartBackupJob";
68       case bEventEndBackupJob:
69          return "bEventEndBackupJob";
70       case bEventStartRestoreJob:
71          return "bEventStartRestoreJob";
72       case bEventEndRestoreJob:
73          return "bEventEndRestoreJob";
74       case bEventStartVerifyJob:
75          return "bEventStartVerifyJob";
76       case bEventEndVerifyJob:
77          return "bEventEndVerifyJob";
78       case bEventBackupCommand:
79          return "bEventBackupCommand";
80       case bEventRestoreCommand:
81          return "bEventRestoreCommand";
82       case bEventEstimateCommand:
83          return "bEventEstimateCommand";
84       case bEventLevel:
85          return "bEventLevel";
86       case bEventSince:
87          return "bEventSince";
88       case bEventCancelCommand:
89          return "bEventCancelCommand";
90       case bEventVssBackupAddComponents:
91          return "bEventVssBackupAddComponents";
92       case bEventVssRestoreLoadComponentMetadata:
93          return "bEventVssRestoreLoadComponentMetadata";
94       case bEventVssRestoreSetComponentsSelected:
95          return "bEventVssRestoreSetComponentsSelected";
96       case bEventRestoreObject:
97          return "bEventRestoreObject";
98       case bEventEndFileSet:
99          return "bEventEndFileSet";
100       case bEventPluginCommand:
101          return "bEventPluginCommand";
102       case bEventVssBeforeCloseRestore:
103          return "bEventVssBeforeCloseRestore";
104       case bEventVssPrepareSnapshot:
105          return "bEventVssPrepareSnapshot";
106       case bEventOptionPlugin:
107          return "bEventOptionPlugin";
108       case bEventHandleBackupFile:
109          return "bEventHandleBackupFile";
110       case bEventComponentInfo:
111          return "bEventComponentInfo";
112       default:
113          return "Unknown";
114    }
115 }
116 
117 
118 /*
119  * Return the real size of the disk based on the size suffix.
120  *
121  * in:
122  *    disksize - the numeric value of the disk size to compute
123  *    suff - the suffix for a disksize value
124  * out:
125  *    uint64_t - the size of the disk computed with suffix
126  */
pluglib_size_suffix(int disksize,char suff)127 uint64_t pluglib_size_suffix(int disksize, char suff)
128 {
129    uint64_t size;
130 
131    switch (suff){
132       case 'G':
133          size = (uint64_t)disksize * 1024 * 1048576;
134          break;
135       case 'M':
136          size = (uint64_t)disksize * 1048576;
137          break;
138       case 'T':
139          size = (uint64_t)disksize * 1048576 * 1048576;
140          break;
141       case 'K':
142       case 'k':
143          size = (uint64_t)disksize * 1024;
144          break;
145       default:
146          size = disksize;
147    }
148    return size;
149 }
150 
151 /*
152  * Return the real size of the disk based on the size suffix.
153  *    This version uses a floating point numbers (double) for computation.
154  *
155  * in:
156  *    disksize - the numeric value of the disk size to compute
157  *    suff - the suffix for a disksize value
158  * out:
159  *    uint64_t - the size of the disk computed with suffix
160  */
pluglib_size_suffix(double disksize,char suff)161 uint64_t pluglib_size_suffix(double disksize, char suff)
162 {
163    uint64_t size;
164 
165    switch (suff){
166       case 'G':
167          size = disksize * 1024.0 * 1048576.0;
168          break;
169       case 'M':
170          size = disksize * 1048576.0;
171          break;
172       case 'T':
173          size = disksize * 1048576.0 * 1048576.0;
174          break;
175       case 'K':
176       case 'k':
177          size = disksize * 1024.0;
178          break;
179       default:
180          size = disksize;
181    }
182    return size;
183 }
184 
185 /*
186  * Creates a path hierarchy on local FS.
187  *  It is used for local restore mode to create a required directory.
188  *  The functionality is similar to 'mkdir -p'.
189  *
190  * TODO: make a support for relative path
191  * TODO: check if we can use findlib/makepath implementation instead
192  *
193  * in:
194  *    bpContext - for Bacula debug and jobinfo messages
195  *    path - a full path to create, does not check if the path is relative,
196  *           could fail in this case
197  * out:
198  *    bRC_OK - path creation was successful
199  *    bRC_Error - on any error
200  */
pluglib_mkpath(bpContext * ctx,char * path,bool isfatal)201 bRC pluglib_mkpath(bpContext* ctx, char* path, bool isfatal)
202 {
203 #ifdef PLUGINPREFIX
204 #define _OLDPREFIX   PLUGINPREFIX
205 #endif
206 #define PLUGINPREFIX    "pluglibmkpath:"
207    struct stat statp;
208    POOL_MEM dir(PM_FNAME);
209    char *p, *q;
210 
211    if (!path){
212       return bRC_Error;
213    }
214    if (stat(path, &statp) == 0){
215       if (S_ISDIR(statp.st_mode)){
216          return bRC_OK;
217       } else {
218          DMSG(ctx, DERROR, "Path %s is not directory\n", path);
219          JMSG(ctx, isfatal ? M_FATAL : M_ERROR, "Path %s is not directory\n", path);
220          return bRC_Error;
221       }
222    }
223    DMSG(ctx, DDEBUG, "mkpath verify dir: %s\n", path);
224    pm_strcpy(dir, path);
225    p = dir.addr() + 1;
226    while (*p && (q = strchr(p, (int)PathSeparator)) != NULL){
227       *q = 0;
228       DMSG(ctx, DDEBUG, "mkpath scanning(1): %s\n", dir.c_str());
229       if (stat(dir.c_str(), &statp) == 0){
230          *q = PathSeparator;
231          p = q + 1;
232          continue;
233       }
234       DMSG0(ctx, DDEBUG, "mkpath will create dir(1).\n");
235       if (mkdir(dir.c_str(), 0750) < 0){
236          /* error */
237          berrno be;
238          DMSG2(ctx, DERROR, "Cannot create directory %s Err=%s\n", dir.c_str(), be.bstrerror());
239          JMSG2(ctx, isfatal ? M_FATAL : M_ERROR, "Cannot create directory %s Err=%s\n", dir.c_str(), be.bstrerror());
240          return bRC_Error;
241       }
242       *q = PathSeparator;
243       p = q + 1;
244    }
245    DMSG0(ctx, DDEBUG, "mkpath will create dir(2).\n");
246    if (mkdir(path, 0750) < 0){
247       /* error */
248       berrno be;
249       DMSG2(ctx, DERROR, "Cannot create directory %s Err=%s\n", path, be.bstrerror());
250       JMSG2(ctx, isfatal ? M_FATAL : M_ERROR, "Cannot create directory %s Err=%s\n", path, be.bstrerror());
251       return bRC_Error;
252    }
253    DMSG0(ctx, DDEBUG, "mkpath finish.\n");
254 #ifdef _OLDPREFIX
255 #define PLUGINPREFIX    _OLDPREFIX
256 #undef _OLDPREFIX
257 #else
258 #undef PLUGINPREFIX
259 #endif
260    return bRC_OK;
261 }
262