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