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 startPluginBackup(bpContext *ctx, struct save_pkt *sp);
57 static bRC endPluginBackup(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 bEventBackupStart:
168 // printf("bpipe-fd: BackupStart\n");
170 case bEventBackupEnd:
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 bEventRestoreStart:
181 // printf("bpipe-fd: RestoreStart\n");
183 case bEventRestoreEnd:
184 // printf("bpipe-fd: RestoreEnd\n");
187 /* Plugin command e.g. plugin = <plugin-name>:<name-space>:command */
188 case bEventPluginCommand:
190 // printf("bpipe-fd: pluginEvent cmd=%s\n", (char *)value);
191 p_ctx->cmd = strdup((char *)value);
192 p = strchr(p_ctx->cmd, ':');
194 printf("Plugin terminator not found: %s\n", (char *)value);
197 *p++ = 0; /* terminate plugin */
201 printf("File terminator not found: %s\n", (char *)value);
204 *p++ = 0; /* terminate file */
208 printf("Reader terminator not found: %s\n", (char *)value);
211 *p++ = 0; /* terminate reader string */
213 printf("bpipe-fd: plugin=%s fname=%s reader=%s writer=%s\n",
214 p_ctx->cmd, p_ctx->fname, p_ctx->reader, p_ctx->writer);
218 printf("bpipe-fd: unknown event=%d\n", event->eventType);
220 bfuncs->getBaculaValue(ctx, bVarFDName, (void *)&name);
221 // printf("FD Name=%s\n", name);
222 // bfuncs->JobMessage(ctx, __FILE__, __LINE__, 1, 0, "JobMesssage message");
223 // bfuncs->DebugMessage(ctx, __FILE__, __LINE__, 1, "DebugMesssage message");
227 static bRC startPluginBackup(bpContext *ctx, struct save_pkt *sp)
229 struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
230 time_t now = time(NULL);
231 sp->fname = p_ctx->fname;
232 sp->statp.st_mode = 0700 | S_IFREG;
233 sp->statp.st_ctime = now;
234 sp->statp.st_mtime = now;
235 sp->statp.st_atime = now;
236 sp->statp.st_size = -1;
237 sp->statp.st_blksize = 4096;
238 sp->statp.st_blocks = 1;
239 p_ctx->backup = true;
240 // printf("bpipe-fd: startPluginBackup\n");
244 static bRC endPluginBackup(bpContext *ctx)
252 static bRC pluginIO(bpContext *ctx, struct io_pkt *io)
254 struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
261 p_ctx->fd = popen(p_ctx->reader, "r");
263 io->io_errno = errno;
264 snprintf(msg, sizeof(msg), "bpipe-fd: reader=%s failed: ERR=%d\n", p_ctx->reader, errno);
265 bfuncs->JobMessage(ctx, __FILE__, __LINE__, 1, 0, msg);
269 printf("bpipe-fd: IO_OPEN reader=%s fd=%p\n", p_ctx->reader, p_ctx->fd);
270 sleep(1); /* let pipe connect */
274 io->status = fread(io->buf, 1, io->count, p_ctx->fd);
275 printf("bpipe-fd: IO_READ buf=%p len=%d\n", io->buf, io->status);
276 if (io->status == 0 && ferror(p_ctx->fd)) {
277 printf("Error reading pipe\n");
280 printf("status=%d\n", io->status);
284 printf("bpipe-fd: IO_WRITE buf=%p len=%d\n", io->buf, io->count);
288 io->status = pclose(p_ctx->fd);
289 printf("bpipe-fd: IO_CLOSE\n");
293 io->offset = p_ctx->offset;
299 static bRC startRestoreFile(bpContext *ctx, const char *cmd)
304 static bRC endRestoreFile(bpContext *ctx)
309 static bRC createFile(bpContext *ctx, struct restore_pkt *rp)
314 static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp)