* After this point, we are dealing with a restore start
*/
- Dmsg1(dbglvl, "plugin restore cmd=%s\n", cmd);
+// Dmsg1(dbglvl, "plugin restore cmd=%s\n", cmd);
if (!(p = strchr(cmd, ':'))) {
- Jmsg1(jcr, M_ERROR, 0, "Malformed plugin command: %s\n", cmd);
+ Jmsg1(jcr, M_ERROR, 0,
+ _("Malformed plugin command. Name not terminated by colon: %s\n"), cmd);
goto bail_out;
}
len = p - cmd;
bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx;
Plugin *plugin = (Plugin *)jcr->plugin;
struct restore_pkt rp;
- struct io_pkt io;
+ mode_t mode;
if (!set_cmd_plugin(bfd, jcr)) {
return CF_ERROR;
rp.where = jcr->where;
rp.RegexWhere = jcr->RegexWhere;
rp.replace = jcr->replace;
+ rp.create_status = CF_ERROR;
+ Dmsg1(dbglvl, "call plugin createFile=%s\n", rp.ofname);
if (plug_func(plugin)->createFile(plugin_ctx, &rp) != bRC_OK) {
return CF_ERROR;
}
- io.pkt_size = sizeof(io);
- io.pkt_end = sizeof(io);
- 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) {
+ if (rp.create_status == CF_ERROR || rp.create_status == CF_CREATED) {
+ return rp.create_status;
+ }
+ mode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY;
+ Dmsg0(dbglvl, "call bopen\n");
+ if ((bopen(bfd, attr->ofname, mode, S_IRUSR | S_IWUSR)) < 0) {
+ berrno be;
+ be.set_errno(bfd->berrno);
+ Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"),
+ attr->ofname, be.bstrerror());
+ Dmsg2(dbglvl,"Could not create %s: ERR=%s\n", attr->ofname, be.bstrerror());
return CF_ERROR;
}
return CF_EXTRACT;
*/
bool plugin_set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
{
+ Dmsg0(dbglvl, "plugin_set_attributes\n");
return true;
}
errno = io.io_errno;
bfd->lerror = io.lerror;
}
+ Dmsg1(dbglvl, "plugin_bclose stat=%d\n", io.status);
return io.status;
}
#undef free
#undef strdup
+#define fi __FILE__
+#define li __LINE__
+
#ifdef __cplusplus
extern "C" {
#endif
*/
switch (event->eventType) {
case bEventJobStart:
-// printf("bpipe-fd: JobStart=%s\n", (char *)value);
+ bfuncs->DebugMessage(ctx, fi, li, 50, "bpipe-fd: JobStart=%s\n", (char *)value);
break;
case bEventJobEnd:
// printf("bpipe-fd: JobEnd\n");
/* Fall-through wanted */
case bEventBackupCommand:
char *p;
- printf("bpipe-fd: pluginEvent cmd=%s\n", (char *)value);
+ bfuncs->DebugMessage(ctx, fi, li, 50, "bpipe-fd: pluginEvent cmd=%s\n", (char *)value);
p_ctx->cmd = strdup((char *)value);
p = strchr(p_ctx->cmd, ':');
if (!p) {
- bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Plugin terminator not found: %s\n", (char *)value);
+ bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Plugin terminator not found: %s\n", (char *)value);
return bRC_Error;
}
*p++ = 0; /* terminate plugin */
p_ctx->fname = p;
p = strchr(p, ':');
if (!p) {
- bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "File terminator not found: %s\n", (char *)value);
+ bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "File terminator not found: %s\n", (char *)value);
return bRC_Error;
}
*p++ = 0; /* terminate file */
p_ctx->reader = p;
p = strchr(p, ':');
if (!p) {
- bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Reader terminator not found: %s\n", (char *)value);
+ bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Reader terminator not found: %s\n", (char *)value);
return bRC_Error;
}
*p++ = 0; /* terminate reader string */
io->io_errno = 0;
switch(io->func) {
case IO_OPEN:
-// printf("bpipe-fd: IO_OPEN\n");
+ bfuncs->DebugMessage(ctx, fi, li, 50, "bpipe-fd: IO_OPEN\n");
if (io->flags & (O_CREAT | O_WRONLY)) {
char *writer_codes = apply_rp_codes(p_ctx);
p_ctx->fd = popen(writer_codes, "w");
- printf("bpipe-fd: IO_OPEN writer=%s\n", writer_codes);
+ bfuncs->DebugMessage(ctx, fi, li, 50, "bpipe-fd: IO_OPEN fd=%d writer=%s\n",
+ p_ctx->fd, writer_codes);
if (!p_ctx->fd) {
io->io_errno = errno;
- bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0,
+ bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0,
"Open pipe writer=%s failed: ERR=%s\n", writer_codes, strerror(errno));
if (writer_codes) {
free(writer_codes);
}
} else {
p_ctx->fd = popen(p_ctx->reader, "r");
-// printf("bpipe-fd: IO_OPEN reader=%s\n", p_ctx->reader);
+ bfuncs->DebugMessage(ctx, fi, li, 50, "bpipe-fd: IO_OPEN fd=%p reader=%s\n",
+ p_ctx->fd, p_ctx->reader);
if (!p_ctx->fd) {
io->io_errno = errno;
- bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0,
+ bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0,
"Open pipe reader=%s failed: ERR=%s\n", p_ctx->reader, strerror(errno));
return bRC_Error;
}
case IO_READ:
if (!p_ctx->fd) {
- bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Logic error: NULL read FD\n");
+ bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Logic error: 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);
+// bfuncs->DebugMessage(ctx, fi, li, 50, "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,
+ bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0,
+ "Pipe read error: ERR=%s\n", strerror(errno));
+ bfuncs->DebugMessage(ctx, fi, li, 50,
"Pipe read error: ERR=%s\n", strerror(errno));
-// printf("Error reading pipe\n");
return bRC_Error;
}
break;
case IO_WRITE:
if (!p_ctx->fd) {
- bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Logic error: NULL write FD\n");
+ bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Logic error: 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,
+ bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0,
"Pipe write error\n");
-// printf("Error writing pipe\n");
+ bfuncs->DebugMessage(ctx, fi, li, 50,
+ "Pipe read error: ERR=%s\n", strerror(errno));
return bRC_Error;
}
break;
case IO_CLOSE:
if (!p_ctx->fd) {
- bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Logic error: NULL FD\n");
+ bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Logic error: NULL FD on bpipe close\n");
return bRC_Error;
}
io->status = pclose(p_ctx->fd);
return bRC_OK;
}
+/*
+ * This is called during restore to create the file (if necessary)
+ * We must return in rp->create_status:
+ *
+ * CF_ERROR -- error
+ * CF_SKIP -- skip processing this file
+ * CF_EXTRACT -- extract the file (i.e.call i/o routines)
+ * CF_CREATED -- created, but no content to extract (typically directories)
+ *
+ */
static bRC createFile(bpContext *ctx, struct restore_pkt *rp)
{
// printf("bpipe-fd: createFile\n");
}
strncpy(((struct plugin_ctx *)ctx->pContext)->where, rp->where, 513);
((struct plugin_ctx *)ctx->pContext)->replace = rp->replace;
+ rp->create_status = CF_EXTRACT;
return bRC_OK;
}
+/*
+ * We will get here if the File is a directory after everything
+ * is written in the directory.
+ */
static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp)
{
// printf("bpipe-fd: setFileAttributes\n");