]> git.sur5r.net Git - bacula/bacula/commitdiff
Pull files from Master
authorKern Sibbald <kern@sibbald.com>
Wed, 23 Nov 2011 12:25:25 +0000 (13:25 +0100)
committerKern Sibbald <kern@sibbald.com>
Sat, 20 Apr 2013 12:50:16 +0000 (14:50 +0200)
bacula/src/stored/ansi_label.c
bacula/src/stored/sd_plugins.c
bacula/src/stored/sd_plugins.h
bacula/src/stored/status.c

index 48d52bd35ef0b609588ccae9ebe6145082a323ad..8f6ca4965eb198eafeaaf8186fb8d2a688c1e507 100644 (file)
@@ -330,8 +330,8 @@ bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName)
          stat = dev->write(label, sizeof(label));
          if (stat != sizeof(label)) {
             berrno be;
-            Jmsg1(jcr, M_FATAL, 0,  _("Could not write ANSI VOL1 label. ERR=%s\n"),
-               be.bstrerror());
+            Jmsg3(jcr, M_FATAL, 0,  _("Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n"),
+               sizeof(label), stat, be.bstrerror());
             return false;
          }
       }
index e77c300f851db42acf9f3c42e76020c8451f6ca4..396d4d2ab9d8ab2e539e8c9a04e5743d44d9a67a 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2007-2009 Free Software Foundation Europe e.V.
+   Copyright (C) 2007-2011 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.
 #include "stored.h"
 #include "sd_plugins.h"
 
-const int dbglvl = 0;
+const int dbglvl = 50;
 const char *plugin_type = "-sd.so";
 
 
 /* Forward referenced functions */
-static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value);
-static bRC baculaSetValue(bpContext *ctx, bwVariable var, void *value);
+static bRC baculaGetValue(bpContext *ctx, bsdrVariable var, void *value);
+static bRC baculaSetValue(bpContext *ctx, bsdwVariable var, void *value);
 static bRC baculaRegisterEvents(bpContext *ctx, ...);
 static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
-  int type, utime_t mtime, const char *msg);
+  int type, utime_t mtime, const char *fmt, ...);
 static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
-  int level, const char *msg);
+  int level, const char *fmt, ...);
+static char *baculaEditDeviceCodes(DCR *dcr, char *omsg, 
+  const char *imsg, const char *cmd);
 
 
 /* Bacula info */
-static bInfo binfo = {
-   sizeof(bFuncs),
-   SD_PLUGIN_INTERFACE_VERSION,
+static bsdInfo binfo = {
+   sizeof(bsdFuncs),
+   SD_PLUGIN_INTERFACE_VERSION
 };
 
 /* Bacula entry points */
-static bFuncs bfuncs = {
-   sizeof(bFuncs),
+static bsdFuncs bfuncs = {
+   sizeof(bsdFuncs),
    SD_PLUGIN_INTERFACE_VERSION,
    baculaRegisterEvents,
    baculaGetValue,
    baculaSetValue,
    baculaJobMsg,
-   baculaDebugMsg
+   baculaDebugMsg,
+   baculaEditDeviceCodes
 };
 
+/* 
+ * Bacula private context
+ */
+struct bacula_ctx {
+   JCR *jcr;                             /* jcr for plugin */
+   bRC  rc;                              /* last return code */
+   bool disabled;                        /* set if plugin disabled */
+};
+
+static bool is_plugin_disabled(bpContext *plugin_ctx)
+{
+   bacula_ctx *b_ctx;
+   if (!plugin_ctx) {
+      return true;
+   }
+   b_ctx = (bacula_ctx *)plugin_ctx->bContext;
+   return b_ctx->disabled;
+}
+
+#ifdef needed
+static bool is_plugin_disabled(JCR *jcr)
+{
+   return is_plugin_disabled(jcr->plugin_ctx);
+}
+#endif
+
 /*
  * Create a plugin event 
  */
-void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
+int generate_plugin_event(JCR *jcr, bsdEventType eventType, void *value)
 {
-   bEvent event;
+   bpContext *plugin_ctx;
+   bsdEvent event;
    Plugin *plugin;
    int i = 0;
+   bRC rc = bRC_OK;
 
-   if (!bplugin_list) {
-      return;
+   if (!bplugin_list || !jcr || !jcr->plugin_ctx_list) {
+      return bRC_OK;                  /* Return if no plugins loaded */
+   }
+   if (jcr->is_job_canceled()) {
+      return bRC_Cancel;
    }
 
    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
    event.eventType = eventType;
 
-   Dmsg2(dbglvl, "plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
+   Dmsg2(dbglvl, "sd-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
 
    foreach_alist(plugin, bplugin_list) {
-      bRC rc;
-      rc = plug_func(plugin)->handlePluginEvent(&plugin_ctx_list[i++], &event, value);
+      plugin_ctx = &plugin_ctx_list[i++];
+      if (is_plugin_disabled(plugin_ctx)) {
+         continue;
+      }
+      rc = sdplug_func(plugin)->handlePluginEvent(plugin_ctx, &event, value);
       if (rc != bRC_OK) {
          break;
       }
    }
 
-   return;
+   return rc;
 }
 
 static void dump_sd_plugin(Plugin *plugin, FILE *fp)
@@ -100,7 +137,7 @@ static void dump_sd_plugin(Plugin *plugin, FILE *fp)
    if (!plugin) {
       return ;
    }
-   pInfo *info = (pInfo *) plugin->pinfo;
+   psdInfo *info = (psdInfo *) plugin->pinfo;
    fprintf(fp, "\tversion=%d\n", info->version);
    fprintf(fp, "\tdate=%s\n", NPRTB(info->plugin_date));
    fprintf(fp, "\tmagic=%s\n", NPRTB(info->plugin_magic));
@@ -112,12 +149,14 @@ static void dump_sd_plugin(Plugin *plugin, FILE *fp)
 
 void load_sd_plugins(const char *plugin_dir)
 {
+   Dmsg0(dbglvl, "Load sd plugins\n");
    if (!plugin_dir) {
+      Dmsg0(dbglvl, "No sd plugin dir!\n");
       return;
    }
-
    bplugin_list = New(alist(10, not_owned_by_alist));
    load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type, NULL);
+   Dmsg1(dbglvl, "num plugins=%d\n", bplugin_list->size());
    dbg_plugin_add_hook(dump_sd_plugin);
 }
 
@@ -129,12 +168,18 @@ void new_plugins(JCR *jcr)
    Plugin *plugin;
    int i = 0;
 
+   Dmsg0(dbglvl, "=== enter new_plugins ===\n");
    if (!bplugin_list) {
+      Dmsg0(dbglvl, "No sd plugin list!\n");
+      return;
+   }
+   if (jcr->is_job_canceled()) {
       return;
    }
 
    int num = bplugin_list->size();
 
+   Dmsg1(dbglvl, "sd-plugin-list size=%d\n", num);
    if (num == 0) {
       return;
    }
@@ -142,12 +187,17 @@ void new_plugins(JCR *jcr)
    jcr->plugin_ctx_list = (bpContext *)malloc(sizeof(bpContext) * num);
 
    bpContext *plugin_ctx_list = jcr->plugin_ctx_list;
-   Dmsg2(dbglvl, "Instantiate plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
+   Dmsg2(dbglvl, "Instantiate sd-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
    foreach_alist(plugin, bplugin_list) {
       /* Start a new instance of each plugin */
-      plugin_ctx_list[i].bContext = (void *)jcr;
+      bacula_ctx *b_ctx = (bacula_ctx *)malloc(sizeof(bacula_ctx));
+      memset(b_ctx, 0, sizeof(bacula_ctx));
+      b_ctx->jcr = jcr;
+      plugin_ctx_list[i].bContext = (void *)b_ctx;
       plugin_ctx_list[i].pContext = NULL;
-      plug_func(plugin)->newPlugin(&plugin_ctx_list[i++]);
+      if (sdplug_func(plugin)->newPlugin(&plugin_ctx_list[i++]) != bRC_OK) {
+         b_ctx->disabled = true;
+      }
    }
 }
 
@@ -164,10 +214,10 @@ void free_plugins(JCR *jcr)
    }
 
    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
-   Dmsg2(dbglvl, "Free instance plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
+   Dmsg2(dbglvl, "Free instance sd-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
    foreach_alist(plugin, bplugin_list) {
       /* Free the plugin instance */
-      plug_func(plugin)->freePlugin(&plugin_ctx_list[i++]);
+      sdplug_func(plugin)->freePlugin(&plugin_ctx_list[i++]);
    }
    free(plugin_ctx_list);
    jcr->plugin_ctx_list = NULL;
@@ -180,18 +230,27 @@ void free_plugins(JCR *jcr)
  *
  * ==============================================================
  */
-static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value)
+static bRC baculaGetValue(bpContext *ctx, bsdrVariable var, void *value)
 {
-   JCR *jcr = (JCR *)(ctx->bContext);
-// Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var);
+   JCR *jcr;
+   if (!ctx) {
+      return bRC_Error;
+   }
+   jcr = ((bacula_ctx *)ctx->bContext)->jcr;
+   if (!jcr) {
+      return bRC_Error;
+   }
    if (!value) {
       return bRC_Error;
    }
-// Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr); 
    switch (var) {
-   case bVarJobId:
+   case bsdVarJobId:
       *((int *)value) = jcr->JobId;
-      Dmsg1(dbglvl, "Bacula: return bVarJobId=%d\n", jcr->JobId);
+      Dmsg1(dbglvl, "sd-plugin: return bVarJobId=%d\n", jcr->JobId);
+      break;
+   case bsdVarJobName:
+      *((char **)value) = jcr->Job;
+      Dmsg1(dbglvl, "Bacula: return Job name=%s\n", jcr->Job);
       break;
    default:
       break;
@@ -199,9 +258,20 @@ static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value)
    return bRC_OK;
 }
 
-static bRC baculaSetValue(bpContext *ctx, bwVariable var, void *value)
+static bRC baculaSetValue(bpContext *ctx, bsdwVariable var, void *value)
 {
-   Dmsg1(dbglvl, "bacula: baculaSetValue var=%d\n", var);
+   JCR *jcr;   
+   if (!value || !ctx) {
+      return bRC_Error;
+   }
+// Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var);
+   jcr = ((bacula_ctx *)ctx->bContext)->jcr;
+   if (!jcr) {
+      return bRC_Error;
+   }
+// Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr); 
+   /* Nothing implemented yet */
+   Dmsg1(dbglvl, "sd-plugin: baculaSetValue var=%d\n", var);
    return bRC_OK;
 }
 
@@ -212,30 +282,52 @@ static bRC baculaRegisterEvents(bpContext *ctx, ...)
 
    va_start(args, ctx);
    while ((event = va_arg(args, uint32_t))) {
-      Dmsg1(dbglvl, "Plugin wants event=%u\n", event);
+      Dmsg1(dbglvl, "sd-Plugin wants event=%u\n", event);
    }
    va_end(args);
    return bRC_OK;
 }
 
 static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
-  int type, utime_t mtime, const char *msg)
+  int type, utime_t mtime, const char *fmt, ...)
 {
-   Dmsg5(dbglvl, "Job message: %s:%d type=%d time=%lld msg=%s\n",
-      file, line, type, mtime, msg);
+   va_list arg_ptr;
+   char buf[2000];
+   JCR *jcr;
+
+   if (ctx) {
+      jcr = ((bacula_ctx *)ctx->bContext)->jcr;
+   } else {
+      jcr = NULL;
+   }
+
+   va_start(arg_ptr, fmt);
+   bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
+   va_end(arg_ptr);
+   Jmsg(jcr, type, mtime, "%s", buf);
    return bRC_OK;
 }
 
 static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
-  int level, const char *msg)
+  int level, const char *fmt, ...)
 {
-   Dmsg4(dbglvl, "Debug message: %s:%d level=%d msg=%s\n",
-      file, line, level, msg);
+   va_list arg_ptr;
+   char buf[2000];
+
+   va_start(arg_ptr, fmt);
+   bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
+   va_end(arg_ptr);
+   d_msg(file, line, level, "%s", buf);
    return bRC_OK;
 }
 
-#ifdef TEST_PROGRAM
+static char *baculaEditDeviceCodes(DCR *dcr, char *omsg, 
+  const char *imsg, const char *cmd)
+{
+   return edit_device_codes(dcr, omsg, imsg, cmd);
+}
 
+#ifdef TEST_PROGRAM
 
 int main(int argc, char *argv[])
 {
@@ -255,16 +347,16 @@ int main(int argc, char *argv[])
    jcr2->JobId = 222;
    new_plugins(jcr2);
 
-   generate_plugin_event(jcr1, bEventJobStart, (void *)"Start Job 1");
-   generate_plugin_event(jcr1, bEventJobEnd);
-   generate_plugin_event(jcr2, bEventJobStart, (void *)"Start Job 1");
+   generate_plugin_event(jcr1, bsdEventJobStart, (void *)"Start Job 1");
+   generate_plugin_event(jcr1, bsdEventJobEnd);
+   generate_plugin_event(jcr2, bsdEventJobStart, (void *)"Start Job 1");
    free_plugins(jcr1);
-   generate_plugin_event(jcr2, bEventJobEnd);
+   generate_plugin_event(jcr2, bsdEventJobEnd);
    free_plugins(jcr2);
 
    unload_plugins();
 
-   Dmsg0(dbglvl, "bacula: OK ...\n");
+   Dmsg0(dbglvl, "sd-plugin: OK ...\n");
    close_memory_pool();
    sm_dump(false);
    return 0;
index 0b317947b5df2d6e08e9b719e309979fc8a6f605..1b7c044edb7afa0daa94504faae6cddc5b431a5e 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2007-2009 Free Software Foundation Europe e.V.
+   Copyright (C) 2007-2011 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.
@@ -71,69 +71,74 @@ extern "C" {
 
 /* Bacula Variable Ids */
 typedef enum {
-  bVarJob       = 1,
-  bVarLevel     = 2,
-  bVarType      = 3,
-  bVarJobId     = 4,
-  bVarClient    = 5,
-  bVarNumVols   = 6,
-  bVarPool      = 7,
-  bVarStorage   = 8,
-  bVarCatalog   = 9,
-  bVarMediaType = 10,
-  bVarJobName   = 11,
-  bVarJobStatus = 12,
-  bVarPriority  = 13,
-  bVarVolumeName = 14,
-  bVarCatalogRes = 15,
-  bVarJobErrors  = 16,
-  bVarJobFiles   = 17,
-  bVarSDJobFiles = 18,
-  bVarSDErrors   = 19,
-  bVarFDJobStatus = 20,
-  bVarSDJobStatus = 21
-} brVariable;
+  bsdVarJob       = 1,
+  bsdVarLevel     = 2,
+  bsdVarType      = 3,
+  bsdVarJobId     = 4,
+  bsdVarClient    = 5,
+  bsdVarNumVols   = 6,
+  bsdVarPool      = 7,
+  bsdVarStorage   = 8,
+  bsdVarCatalog   = 9,
+  bsdVarMediaType = 10,
+  bsdVarJobName   = 11,
+  bsdVarJobStatus = 12,
+  bsdVarPriority  = 13,
+  bsdVarVolumeName = 14,
+  bsdVarCatalogRes = 15,
+  bsdVarJobErrors  = 16,
+  bsdVarJobFiles   = 17,
+  bsdVarSDJobFiles = 18,
+  bsdVarSDErrors   = 19,
+  bsdVarFDJobStatus = 20,
+  bsdVarSDJobStatus = 21
+} bsdrVariable;
 
 typedef enum {
-  bwVarJobReport  = 1,
-  bwVarVolumeName = 2,
-  bwVarPriority   = 3,
-  bwVarJobLevel   = 4
-} bwVariable;
+  bsdwVarJobReport  = 1,
+  bsdwVarVolumeName = 2,
+  bsdwVarPriority   = 3,
+  bsdwVarJobLevel   = 4
+} bsdwVariable;
 
 
 typedef enum {
-  bEventJobStart      = 1,
-  bEventJobEnd        = 2
-} bEventType;
-
-typedef struct s_bEvent {
+  bsdEventJobStart       = 1,
+  bsdEventJobEnd         = 2,
+  bsdEventDeviceOpen     = 3,
+  bsdEventDeviceTryOpen  = 4,
+  bsdEventDeviceClose    = 5
+} bsdEventType;
+
+typedef struct s_bsdEvent {
    uint32_t eventType;
-} bEvent;
+} bsdEvent;
 
-typedef struct s_baculaInfo {
+typedef struct s_sdbaculaInfo {
    uint32_t size;
    uint32_t version;  
-} bInfo;
+} bsdInfo;
 
 /* Bacula interface version and function pointers */
-typedef struct s_baculaFuncs {  
+typedef struct s_sdbaculaFuncs {  
    uint32_t size;
    uint32_t version;
    bRC (*registerBaculaEvents)(bpContext *ctx, ...);
-   bRC (*getBaculaValue)(bpContext *ctx, brVariable var, void *value);
-   bRC (*setBaculaValue)(bpContext *ctx, bwVariable var, void *value);
+   bRC (*getBaculaValue)(bpContext *ctx, bsdrVariable var, void *value);
+   bRC (*setBaculaValue)(bpContext *ctx, bsdwVariable var, void *value);
    bRC (*JobMessage)(bpContext *ctx, const char *file, int line, 
-       int type, utime_t mtime, const char *msg);     
+       int type, utime_t mtime, const char *fmt, ...);
    bRC (*DebugMessage)(bpContext *ctx, const char *file, int line,
-       int level, const char *msg);
-} bFuncs;
+       int level, const char *fmt, ...);
+   char *(*EditDeviceCodes)(DCR *dcr, char *omsg,
+       const char *imsg, const char *cmd);
+} bsdFuncs;
 
 /* Bacula Subroutines */
 void load_sd_plugins(const char *plugin_dir);
 void new_plugins(JCR *jcr);
 void free_plugins(JCR *jcr);
-void generate_plugin_event(JCR *jcr, bEventType event, void *value=NULL);
+int generate_plugin_event(JCR *jcr, bsdEventType event, void *value=NULL);
 
 
 
@@ -144,15 +149,15 @@ void generate_plugin_event(JCR *jcr, bEventType event, void *value=NULL);
  ****************************************************************************/
 
 typedef enum {
-  pVarName = 1,
-  pVarDescription = 2
-} pVariable;
+  psdVarName = 1,
+  psdVarDescription = 2
+} psdVariable;
 
 
-#define SD_PLUGIN_MAGIC     "*DirPluginData*" 
+#define SD_PLUGIN_MAGIC     "*SDPluginData*" 
 #define SD_PLUGIN_INTERFACE_VERSION  1
 
-typedef struct s_pluginInfo {
+typedef struct s_sdpluginInfo {
    uint32_t size;
    uint32_t version;
    const char *plugin_magic;
@@ -161,20 +166,23 @@ typedef struct s_pluginInfo {
    const char *plugin_date;
    const char *plugin_version;
    const char *plugin_description;
-} pInfo;
+} psdInfo;
 
-typedef struct s_pluginFuncs {  
+/* 
+ * Functions that must be defined in every plugin
+ */
+typedef struct s_sdpluginFuncs {  
    uint32_t size;
    uint32_t version;
    bRC (*newPlugin)(bpContext *ctx);
    bRC (*freePlugin)(bpContext *ctx);
-   bRC (*getPluginValue)(bpContext *ctx, pVariable var, void *value);
-   bRC (*setPluginValue)(bpContext *ctx, pVariable var, void *value);
-   bRC (*handlePluginEvent)(bpContext *ctx, bEvent *event, void *value);
-} pFuncs;
+   bRC (*getPluginValue)(bpContext *ctx, psdVariable var, void *value);
+   bRC (*setPluginValue)(bpContext *ctx, psdVariable var, void *value);
+   bRC (*handlePluginEvent)(bpContext *ctx, bsdEvent *event, void *value);
+} psdFuncs;
 
-#define plug_func(plugin) ((pFuncs *)(plugin->pfuncs))
-#define plug_info(plugin) ((pInfo *)(plugin->pinfo))
+#define sdplug_func(plugin) ((psdFuncs *)(plugin->pfuncs))
+#define sdplug_info(plugin) ((psdInfo *)(plugin->pinfo))
 
 #ifdef __cplusplus
 }
index 1d51e1f2dd6bb64ddd2c735680aa33c9af300acd..7c29ed6d066290e61c5911f85a1c736582fbb97e 100644 (file)
@@ -225,7 +225,6 @@ static void list_status_header(STATUS_PKT *sp)
    len = Mmsg(msg, _("Daemon started %s. Jobs: run=%d, running=%d.\n"),
         dt, num_jobs_run, job_count());
    sendit(msg, len, sp);
-
    len = Mmsg(msg, _(" Heap: heap=%s smbytes=%s max_bytes=%s bufs=%s max_bufs=%s\n"),
          edit_uint64_with_commas((char *)sbrk(0)-(char *)start_heap, b1),
          edit_uint64_with_commas(sm_bytes, b2),
@@ -233,9 +232,10 @@ static void list_status_header(STATUS_PKT *sp)
          edit_uint64_with_commas(sm_buffers, b4),
          edit_uint64_with_commas(sm_max_buffers, b5));
    sendit(msg, len, sp);
-   len = Mmsg(msg, "Sizes: boffset_t=%d size_t=%d int32_t=%d int64_t=%d\n", 
-         (int)sizeof(boffset_t), (int)sizeof(size_t), (int)sizeof(int32_t),
-         (int)sizeof(int64_t));
+   len = Mmsg(msg, " Sizes: boffset_t=%d size_t=%d int32_t=%d int64_t=%d "
+              "mode=%d,%d\n", 
+              (int)sizeof(boffset_t), (int)sizeof(size_t), (int)sizeof(int32_t),
+              (int)sizeof(int64_t), (int)DEVELOPER_MODE, (int)BEEF);
    sendit(msg, len, sp);
 }
 
@@ -327,6 +327,7 @@ static void send_device_status(DEVICE *dev, STATUS_PKT *sp)
 {
    POOL_MEM msg(PM_MESSAGE);
    int len;
+   char *locked;
 
    len = Mmsg(msg, _("Configured device capabilities:\n"));
    sendit(msg, len, sp);
@@ -368,6 +369,12 @@ static void send_device_status(DEVICE *dev, STATUS_PKT *sp)
               dev->num_reserved(), dev->blocked());
    sendit(msg, len, sp);
 
+   locked = dev->lock_holder;
+   if (locked) {
+      len = Mmsg(msg, _("Waiting for device locked by: %s\n"), locked);
+      sendit(msg, len, sp);
+   }
+
    len = Mmsg(msg, _("Device parameters:\n"));
    sendit(msg, len, sp);