2 Bacula® - The Network Backup Solution
4 Copyright (C) 2007-2008 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation, which is
11 listed in the file LICENSE.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * A simple pipe plugin for Bacula
31 * Kern Sibbald, October 2007
34 #include "fd-plugins.h"
44 #define PLUGIN_LICENSE "GPL"
45 #define PLUGIN_AUTHOR "Kern Sibbald"
46 #define PLUGIN_DATE "January 2008"
47 #define PLUGIN_VERSION "1"
48 #define PLUGIN_DESCRIPTION "Test File Daemon Plugin"
50 /* Forward referenced functions */
51 static bRC newPlugin(bpContext *ctx);
52 static bRC freePlugin(bpContext *ctx);
53 static bRC getPluginValue(bpContext *ctx, pVariable var, void *value);
54 static bRC setPluginValue(bpContext *ctx, pVariable var, void *value);
55 static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value);
56 static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp);
57 static bRC endBackupFile(bpContext *ctx);
58 static bRC pluginIO(bpContext *ctx, struct io_pkt *io);
59 static bRC startRestoreFile(bpContext *ctx, const char *cmd);
60 static bRC endRestoreFile(bpContext *ctx);
61 static bRC createFile(bpContext *ctx, struct restore_pkt *rp);
62 static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp);
65 /* Pointers to Bacula functions */
66 static bFuncs *bfuncs = NULL;
67 static bInfo *binfo = NULL;
69 static pInfo pluginInfo = {
71 PLUGIN_INTERFACE_VERSION,
80 static pFuncs pluginFuncs = {
82 PLUGIN_INTERFACE_VERSION,
84 /* Entry points into plugin */
85 newPlugin, /* new plugin instance */
86 freePlugin, /* free plugin instance */
109 bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs)
111 bfuncs = lbfuncs; /* set Bacula funct pointers */
113 // printf("bpipe-fd: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version);
115 *pinfo = &pluginInfo; /* return pointer to our info */
116 *pfuncs = &pluginFuncs; /* return pointer to our functions */
123 // printf("bpipe-fd: Unloaded\n");
127 static bRC newPlugin(bpContext *ctx)
129 struct plugin_ctx *p_ctx = (struct plugin_ctx *)malloc(sizeof(struct plugin_ctx));
130 memset(p_ctx, 0, sizeof(struct plugin_ctx));
131 ctx->pContext = (void *)p_ctx; /* set our context pointer */
135 static bRC freePlugin(bpContext *ctx)
137 struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
145 static bRC getPluginValue(bpContext *ctx, pVariable var, void *value)
150 static bRC setPluginValue(bpContext *ctx, pVariable var, void *value)
155 static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value)
157 struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
160 switch (event->eventType) {
162 // printf("bpipe-fd: JobStart=%s\n", (char *)value);
165 // printf("bpipe-fd: JobEnd\n");
167 case bEventStartBackupJob:
168 // printf("bpipe-fd: BackupStart\n");
170 case bEventEndBackupJob:
171 // printf("bpipe-fd: BackupEnd\n");
174 // printf("bpipe-fd: JobLevel=%c %d\n", (int)value, (int)value);
177 // printf("bpipe-fd: since=%d\n", (int)value);
180 case bEventStartRestoreJob:
181 printf("bpipe-fd: StartRestoreJob\n");
184 case bEventEndRestoreJob:
185 printf("bpipe-fd: EndRestoreJob\n");
188 /* Plugin command e.g. plugin = <plugin-name>:<name-space>:read command:write command */
189 case bEventRestoreCommand:
190 printf("bpipe-fd: EventRestoreCommand cmd=%s\n", (char *)value);
191 case bEventBackupCommand:
193 printf("bpipe-fd: pluginEvent cmd=%s\n", (char *)value);
194 p_ctx->cmd = strdup((char *)value);
195 p = strchr(p_ctx->cmd, ':');
197 bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Plugin terminator not found: %s\n", (char *)value);
200 *p++ = 0; /* terminate plugin */
204 bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "File terminator not found: %s\n", (char *)value);
207 *p++ = 0; /* terminate file */
211 bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Reader terminator not found: %s\n", (char *)value);
214 *p++ = 0; /* terminate reader string */
216 printf("bpipe-fd: plugin=%s fname=%s reader=%s writer=%s\n",
217 p_ctx->cmd, p_ctx->fname, p_ctx->reader, p_ctx->writer);
221 printf("bpipe-fd: unknown event=%d\n", event->eventType);
223 // bfuncs->getBaculaValue(ctx, bVarFDName, (void *)&name);
224 // printf("FD Name=%s\n", name);
225 // bfuncs->JobMessage(ctx, __FILE__, __LINE__, 1, 0, "JobMesssage message");
226 // bfuncs->DebugMessage(ctx, __FILE__, __LINE__, 1, "DebugMesssage message");
230 static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp)
232 struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
233 time_t now = time(NULL);
234 sp->fname = p_ctx->fname;
235 sp->statp.st_mode = 0700 | S_IFREG;
236 sp->statp.st_ctime = now;
237 sp->statp.st_mtime = now;
238 sp->statp.st_atime = now;
239 sp->statp.st_size = -1;
240 sp->statp.st_blksize = 4096;
241 sp->statp.st_blocks = 1;
242 p_ctx->backup = true;
243 // printf("bpipe-fd: startBackupFile\n");
247 static bRC endBackupFile(bpContext *ctx)
250 * We would return bRC_More if we wanted startBackupFile to be
251 * called again to backup another file
253 // printf("bpipe-fd: endBackupFile\n");
260 static bRC pluginIO(bpContext *ctx, struct io_pkt *io)
262 struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
268 printf("bpipe-fd: IO_OPEN\n");
269 if (io->flags & (O_CREAT | O_WRONLY)) {
270 p_ctx->fd = popen(p_ctx->writer, "w");
271 printf("bpipe-fd: IO_OPEN writer=%s\n", p_ctx->writer);
273 io->io_errno = errno;
274 bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0,
275 "bpipe-fd: writer=%s failed: ERR=%d\n", p_ctx->writer, errno);
279 p_ctx->fd = popen(p_ctx->reader, "r");
280 printf("bpipe-fd: IO_OPEN reader=%s\n", p_ctx->reader);
282 io->io_errno = errno;
283 bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0,
284 "bpipe-fd: reader=%s failed: ERR=%d\n", p_ctx->reader, errno);
288 sleep(1); /* let pipe connect */
293 bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "NULL read FD\n");
296 io->status = fread(io->buf, 1, io->count, p_ctx->fd);
297 printf("bpipe-fd: IO_READ buf=%p len=%d\n", io->buf, io->status);
298 if (io->status == 0 && ferror(p_ctx->fd)) {
299 bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Pipe read error\n");
300 printf("Error reading pipe\n");
303 // printf("status=%d\n", io->status);
308 bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "NULL write FD\n");
311 printf("bpipe-fd: IO_WRITE fd=%p buf=%p len=%d\n", p_ctx->fd, io->buf, io->count);
312 io->status = fwrite(io->buf, 1, io->count, p_ctx->fd);
313 printf("bpipe-fd: IO_WRITE buf=%p len=%d\n", io->buf, io->status);
314 if (io->status == 0 && ferror(p_ctx->fd)) {
315 bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Pipe write error\n");
316 printf("Error writing pipe\n");
319 // printf("status=%d\n", io->status);
324 bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "NULL FD\n");
327 io->status = pclose(p_ctx->fd);
328 printf("bpipe-fd: IO_CLOSE\n");
332 io->offset = p_ctx->offset;
338 static bRC startRestoreFile(bpContext *ctx, const char *cmd)
340 printf("bpipe-fd: startRestoreFile cmd=%s\n", cmd);
344 static bRC endRestoreFile(bpContext *ctx)
346 printf("bpipe-fd: endRestoreFile\n");
350 static bRC createFile(bpContext *ctx, struct restore_pkt *rp)
352 printf("bpipe-fd: createFile\n");
356 static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp)
358 printf("bpipe-fd: setFileAttributes\n");