]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/plugins/fd/bpipe-fd.c
85aa062bca5c4e33a68a70970da9f51f88182bf5
[bacula/bacula] / bacula / src / plugins / fd / bpipe-fd.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2008 Free Software Foundation Europe e.V.
5
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.
12
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.
17
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
21    02110-1301, USA.
22
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.
27 */
28 /*
29  * A simple pipe plugin for Bacula
30  *
31  *  Kern Sibbald, October 2007
32  *
33  */
34 #include "fd-plugins.h"
35
36 #undef malloc
37 #undef free
38 #undef strdup
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
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"
49
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);
63
64
65 /* Pointers to Bacula functions */
66 static bFuncs *bfuncs = NULL;
67 static bInfo  *binfo = NULL;
68
69 static pInfo pluginInfo = {
70    sizeof(pluginInfo),
71    PLUGIN_INTERFACE_VERSION,
72    PLUGIN_MAGIC,
73    PLUGIN_LICENSE,
74    PLUGIN_AUTHOR,
75    PLUGIN_DATE,
76    PLUGIN_VERSION,
77    PLUGIN_DESCRIPTION,
78 };
79
80 static pFuncs pluginFuncs = {
81    sizeof(pluginFuncs),
82    PLUGIN_INTERFACE_VERSION,
83
84    /* Entry points into plugin */
85    newPlugin,                         /* new plugin instance */
86    freePlugin,                        /* free plugin instance */
87    getPluginValue,
88    setPluginValue,
89    handlePluginEvent,
90    startPluginBackup,
91    endPluginBackup,
92    startRestoreFile,
93    endRestoreFile,
94    pluginIO,
95    createFile,
96    setFileAttributes
97 };
98
99 struct plugin_ctx {
100    boffset_t offset;
101    FILE *fd;
102    bool backup;
103    char *cmd;
104    char *fname;
105    char *reader;
106    char *writer;
107 };
108
109 bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs)
110 {
111    bfuncs = lbfuncs;                  /* set Bacula funct pointers */
112    binfo  = lbinfo;
113 // printf("bpipe-fd: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version);
114
115    *pinfo  = &pluginInfo;             /* return pointer to our info */
116    *pfuncs = &pluginFuncs;            /* return pointer to our functions */
117
118    return bRC_OK;
119 }
120
121 bRC unloadPlugin() 
122 {
123 // printf("bpipe-fd: Unloaded\n");
124    return bRC_OK;
125 }
126
127 static bRC newPlugin(bpContext *ctx)
128 {
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 */
132    return bRC_OK;
133 }
134
135 static bRC freePlugin(bpContext *ctx)
136 {
137    struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
138    if (p_ctx->cmd) {
139       free(p_ctx->cmd);
140    }
141    free(p_ctx);
142    return bRC_OK;
143 }
144
145 static bRC getPluginValue(bpContext *ctx, pVariable var, void *value) 
146 {
147    return bRC_OK;
148 }
149
150 static bRC setPluginValue(bpContext *ctx, pVariable var, void *value) 
151 {
152    return bRC_OK;
153 }
154
155 static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value)
156 {
157    struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
158    char *name;
159
160    switch (event->eventType) {
161    case bEventJobStart:
162 //    printf("bpipe-fd: JobStart=%s\n", (char *)value);
163       break;
164    case bEventJobEnd:
165 //    printf("bpipe-fd: JobEnd\n");
166       break;
167    case bEventBackupStart:
168 //    printf("bpipe-fd: BackupStart\n");
169       break;
170    case bEventBackupEnd:
171 //    printf("bpipe-fd: BackupEnd\n");
172       break;
173    case bEventLevel:
174 //    printf("bpipe-fd: JobLevel=%c %d\n", (int)value, (int)value);
175       break;
176    case bEventSince:
177 //    printf("bpipe-fd: since=%d\n", (int)value);
178       break;
179
180    case bEventRestoreStart: 
181 //    printf("bpipe-fd: RestoreStart\n");
182       break;
183    case bEventRestoreEnd:
184 //    printf("bpipe-fd: RestoreEnd\n");
185       break;
186
187    /* Plugin command e.g. plugin = <plugin-name>:<name-space>:command */
188    case bEventPluginCommand:
189       char *p;
190 //    printf("bpipe-fd: pluginEvent cmd=%s\n", (char *)value);
191       p_ctx->cmd = strdup((char *)value);
192       p = strchr(p_ctx->cmd, ':');
193       if (!p) {
194          printf("Plugin terminator not found: %s\n", (char *)value);
195          return bRC_Error;
196       }
197       *p++ = 0;           /* terminate plugin */
198       p_ctx->fname = p;
199       p = strchr(p, ':');
200       if (!p) {
201          printf("File terminator not found: %s\n", (char *)value);
202          return bRC_Error;
203       }
204       *p++ = 0;           /* terminate file */
205       p_ctx->reader = p;
206       p = strchr(p, ':');
207       if (!p) {
208          printf("Reader terminator not found: %s\n", (char *)value);
209          return bRC_Error;
210       }
211       *p++ = 0;           /* terminate reader string */
212       p_ctx->writer = p;
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);
215       break;
216
217    default:
218       printf("bpipe-fd: unknown event=%d\n", event->eventType);
219    }
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");
224    return bRC_OK;
225 }
226
227 static bRC startPluginBackup(bpContext *ctx, struct save_pkt *sp)
228 {
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");
241    return bRC_OK;
242 }
243
244 static bRC endPluginBackup(bpContext *ctx)
245 {
246    return bRC_OK;
247 }
248
249 /*
250  * Do actual I/O
251  */
252 static bRC pluginIO(bpContext *ctx, struct io_pkt *io)
253 {
254    struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
255    char msg[200];
256     
257    io->status = 0;
258    io->io_errno = 0;
259    switch(io->func) {
260    case IO_OPEN:
261       p_ctx->fd = popen(p_ctx->reader, "r");
262       if (!p_ctx->fd) {
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);
266          printf("%s", msg);
267          return bRC_Error;
268       }
269       printf("bpipe-fd: IO_OPEN reader=%s fd=%p\n", p_ctx->reader, p_ctx->fd);
270       sleep(1);                 /* let pipe connect */
271       break;
272
273    case IO_READ:
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");
278          return bRC_Error;
279       }
280       printf("status=%d\n", io->status);
281       break;
282
283    case IO_WRITE:
284       printf("bpipe-fd: IO_WRITE buf=%p len=%d\n", io->buf, io->count);
285       break;
286
287    case IO_CLOSE:
288       io->status = pclose(p_ctx->fd);
289       printf("bpipe-fd: IO_CLOSE\n");
290       break;
291
292    case IO_SEEK:
293       io->offset = p_ctx->offset;
294       break;
295    }
296    return bRC_OK;
297 }
298
299 static bRC startRestoreFile(bpContext *ctx, const char *cmd)
300 {
301    return bRC_OK;
302 }
303
304 static bRC endRestoreFile(bpContext *ctx)
305 {
306    return bRC_OK;
307 }
308
309 static bRC createFile(bpContext *ctx, struct restore_pkt *rp)
310 {
311    return bRC_OK;
312 }
313
314 static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp)
315 {
316    return bRC_OK;
317 }
318
319
320 #ifdef __cplusplus
321 }
322 #endif