int i = 0;
bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
- Dmsg1(000, "Read plugin stream string=%s\n", name);
+ Dmsg1(100, "Read plugin stream string=%s\n", name);
skip_nonspaces(&p); /* skip over jcr->JobFiles */
skip_spaces(&p);
start = *p == '1';
* After this point, we are dealing with a restore start
*/
- Dmsg1(000, "plugin cmd=%s\n", cmd);
+ Dmsg1(100, "plugin restore cmd=%s\n", cmd);
if (!(p = strchr(cmd, ':'))) {
Jmsg1(jcr, M_ERROR, 0, "Malformed plugin command: %s\n", cmd);
goto bail_out;
*/
foreach_alist(plugin, plugin_list) {
bEvent event;
- Dmsg3(000, "plugin=%s cmd=%s len=%d\n", plugin->file, cmd, len);
+ Dmsg3(100, "plugin=%s cmd=%s len=%d\n", plugin->file, cmd, len);
if (strncmp(plugin->file, cmd, len) != 0) {
i++;
continue;
}
- Dmsg1(000, "Restore Command plugin = %s\n", cmd);
+ Dmsg1(100, "Restore Command plugin = %s\n", cmd);
event.eventType = bEventRestoreCommand;
if (plug_func(plugin)->handlePluginEvent(&plugin_ctx_list[i],
&event, cmd) != bRC_OK) {
*/
int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
{
-// bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx;
-// Plugin *plugin = (Plugin *)jcr->plugin;
+ bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx;
+ Plugin *plugin = (Plugin *)jcr->plugin;
+ struct restore_pkt rp;
+ struct io_pkt io;
+
if (!set_cmd_plugin(bfd, jcr)) {
return CF_ERROR;
}
+ rp.stream = attr->stream;
+ rp.data_stream = attr->data_stream;
+ rp.type = attr->type;
+ rp.file_index = attr->file_index;
+ rp.LinkFI = attr->LinkFI;
+ rp.uid = attr->uid;
+ rp.statp = attr->statp; /* structure assignment */
+ rp.attrEx = attr->attrEx;
+ rp.ofname = attr->ofname;
+ rp.olname = attr->olname;
+ if (plug_func(plugin)->createFile(plugin_ctx, &rp) != bRC_OK) {
+ return CF_ERROR;
+ }
+ io.func = IO_OPEN;
+ io.count = 0;
+ io.buf = NULL;
+ io.mode = 0777 & attr->statp.st_mode;
+ io.flags = O_WRONLY;
+ if (plug_func(plugin)->pluginIO(plugin_ctx, &io) != bRC_OK) {
+ return CF_ERROR;
+ }
return CF_EXTRACT;
}
io.func = IO_OPEN;
io.count = 0;
io.buf = NULL;
+ io.mode = mode;
+ io.flags = flags;
plug_func(plugin)->pluginIO(plugin_ctx, &io);
return io.status;
}
* This packet is used for file restore info transfer.
*/
struct restore_pkt {
+ int32_t stream; /* attribute stream id */
+ int32_t data_stream; /* id of data stream to follow */
+ int32_t type; /* file type FT */
+ int32_t file_index; /* file index */
+ int32_t LinkFI; /* file index to data if hard link */
+ uid_t uid; /* userid */
+ struct stat statp; /* decoded stat packet */
+ const char *attrEx; /* extended attributes if any */
+ const char *ofname; /* output filename */
+ const char *olname; /* output link name */
};
enum {
struct io_pkt {
int32_t func; /* Function code */
int32_t count; /* read/write count */
+ mode_t mode; /* permissions for created files */
+ int32_t flags; /* open flags (e.g. O_WRONLY ...) */
char *buf; /* read/write buffer */
int32_t status; /* return status */
int32_t io_errno; /* errno code */
break;
case STREAM_PLUGIN_NAME:
- Dmsg1(000, "stream_plugin_name=%s\n", sd->msg);
+ Dmsg1(000, "restore stream_plugin_name=%s\n", sd->msg);
plugin_name_stream(jcr, sd->msg);
break;
#include "bacula.h"
#include "find.h"
-int (*plugin_bopen)(JCR *jcr, const char *fname, int flags, mode_t mode) = NULL;
-int (*plugin_bclose)(JCR *jcr) = NULL;
-ssize_t (*plugin_bread)(JCR *jcr, void *buf, size_t count) = NULL;
-ssize_t (*plugin_bwrite)(JCR *jcr, void *buf, size_t count) = NULL;
+int (*plugin_bopen)(JCR *jcr, const char *fname, int flags, mode_t mode) = NULL;
+int (*plugin_bclose)(JCR *jcr) = NULL;
+ssize_t (*plugin_bread)(JCR *jcr, void *buf, size_t count) = NULL;
+ssize_t (*plugin_bwrite)(JCR *jcr, void *buf, size_t count) = NULL;
boffset_t (*plugin_blseek)(JCR *jcr, boffset_t offset, int whence) = NULL;
unix_name_to_win32(&win32_fname, (char *)fname);
+ if (bfd->cmd_plugin && plugin_bopen) {
+ int rtnstat;
+ Dmsg1(000, "call plugin_bopen fname=%s\n", fname);
+ rtnstat = plugin_bopen(bfd->jcr, fname, flags, mode);
+ free_pool_memory(win32_fname_wchar);
+ free_pool_memory(win32_fname);
+ return rtnstat;
+ }
+
if (!(p_CreateFileA || p_CreateFileW))
return 0;
if (bfd->mode == BF_CLOSED) {
return 0;
}
+
+ if (bfd->cmd_plugin && plugin_bclose) {
+ stat = plugin_bclose(bfd->jcr);
+ goto all_done;
+ }
+
if (bfd->use_backup_api && bfd->mode == BF_READ) {
BYTE buf[10];
if (!bfd->lpContext && !p_BackupRead(bfd->fh,
stat = -1;
errno = b_errno_win32;
}
+
+all_done:
bfd->mode = BF_CLOSED;
bfd->lpContext = NULL;
bfd->cmd_plugin = false;
{
bfd->rw_bytes = 0;
+ if (bfd->cmd_plugin && plugin_bread) {
+ return plugin_bread(bfd->jcr, buf, count);
+ }
+
if (bfd->use_backup_api) {
if (!p_BackupRead(bfd->fh,
(BYTE *)buf,
{
bfd->rw_bytes = 0;
+ if (bfd->cmd_plugin && plugin_bwrite) {
+ return plugin_bwrite(bfd->jcr, buf, count);
+ }
+
if (bfd->use_backup_api) {
if (!p_BackupWrite(bfd->fh,
(BYTE *)buf,
LONG offset_high = (LONG)(offset >> 32);
DWORD dwResult;
+ if (bfd->cmd_plugin && plugin_bwrite) {
+ return plugin_blseek(bfd->jcr, offset, whence);
+ }
+
dwResult = SetFilePointer(bfd->fh, offset_low, &offset_high, whence);
if (dwResult == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
/* Normal file open */
Dmsg1(100, "open file %s\n", fname);
+
/* We use fnctl to set O_NOATIME if requested to avoid open error */
bfd->fid = open(fname, flags & ~O_NOATIME, mode);
+
/* Set O_NOATIME if possible */
if (bfd->fid != -1 && flags & O_NOATIME) {
int oldflags = fcntl(bfd->fid, F_GETFL, 0);
Dmsg1(400, "Close file %d\n", bfd->fid);
if (bfd->cmd_plugin && plugin_bclose) {
- return plugin_bclose(bfd->jcr);
+ stat = plugin_bclose(bfd->jcr);
+ bfd->fid = -1;
+ bfd->cmd_plugin = false;
}
if (bfd->fid == -1) {
boffset_t blseek(BFILE *bfd, boffset_t offset, int whence)
{
- boffset_t pos;
+ boffset_t pos;
if (bfd->cmd_plugin && plugin_bwrite) {
return plugin_blseek(bfd->jcr, offset, whence);
}
- pos = (boffset_t)lseek(bfd->fid, (off_t)offset, whence);
- bfd->berrno = errno;
- return pos;
+ pos = (boffset_t)lseek(bfd->fid, (off_t)offset, whence);
+ bfd->berrno = errno;
+ return pos;
}
#endif
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2003-2007 Free Software Foundation Europe e.V.
+ Copyright (C) 2003-2008 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
static bRC pluginIO(bpContext *ctx, struct io_pkt *io)
{
struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
- char msg[200];
io->status = 0;
io->io_errno = 0;
switch(io->func) {
case IO_OPEN:
- p_ctx->fd = popen(p_ctx->reader, "r");
- if (!p_ctx->fd) {
- io->io_errno = errno;
- snprintf(msg, sizeof(msg), "bpipe-fd: reader=%s failed: ERR=%d\n", p_ctx->reader, errno);
- bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, msg);
- printf("%s", msg);
- return bRC_Error;
+ printf("bpipe-fd: IO_OPEN\n");
+ if (io->flags & (O_CREAT | O_WRONLY)) {
+ p_ctx->fd = popen(p_ctx->writer, "w");
+ printf("bpipe-fd: IO_OPEN writer=%s\n", p_ctx->writer);
+ if (!p_ctx->fd) {
+ io->io_errno = errno;
+ bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0,
+ "bpipe-fd: writer=%s failed: ERR=%d\n", p_ctx->writer, errno);
+ return bRC_Error;
+ }
+ } else {
+ p_ctx->fd = popen(p_ctx->reader, "r");
+ printf("bpipe-fd: IO_OPEN reader=%s\n", p_ctx->reader);
+ if (!p_ctx->fd) {
+ io->io_errno = errno;
+ bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0,
+ "bpipe-fd: reader=%s failed: ERR=%d\n", p_ctx->reader, errno);
+ return bRC_Error;
+ }
}
- printf("bpipe-fd: IO_OPEN reader=%s fd=%p\n", p_ctx->reader, p_ctx->fd);
sleep(1); /* let pipe connect */
break;
case IO_READ:
if (!p_ctx->fd) {
- bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "NULL FD\n");
+ bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "NULL read FD\n");
return bRC_Error;
}
io->status = fread(io->buf, 1, io->count, p_ctx->fd);
printf("bpipe-fd: IO_READ buf=%p len=%d\n", io->buf, io->status);
if (io->status == 0 && ferror(p_ctx->fd)) {
- bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Pipe I/O error\n");
+ bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Pipe read error\n");
printf("Error reading pipe\n");
return bRC_Error;
}
- printf("status=%d\n", io->status);
+// printf("status=%d\n", io->status);
break;
case IO_WRITE:
- printf("bpipe-fd: IO_WRITE buf=%p len=%d\n", io->buf, io->count);
+ if (!p_ctx->fd) {
+ bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "NULL write FD\n");
+ return bRC_Error;
+ }
+ printf("bpipe-fd: IO_WRITE fd=%p buf=%p len=%d\n", p_ctx->fd, io->buf, io->count);
+ io->status = fwrite(io->buf, 1, io->count, p_ctx->fd);
+ printf("bpipe-fd: IO_WRITE buf=%p len=%d\n", io->buf, io->status);
+ if (io->status == 0 && ferror(p_ctx->fd)) {
+ bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Pipe write error\n");
+ printf("Error writing pipe\n");
+ return bRC_Error;
+ }
+// printf("status=%d\n", io->status);
break;
case IO_CLOSE: