]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/ua_label.c
Add new files
[bacula/bacula] / bacula / src / dird / ua_label.c
index a27a844dd1f4b483276f0ae2817732f831e834b7..be0746b3239ce59e3acc3980181855fe44e3fa10 100644 (file)
@@ -41,10 +41,10 @@ typedef struct s_vol_list {
 /* Forward referenced functions */
 static int do_label(UAContext *ua, char *cmd, int relabel);
 static void label_from_barcodes(UAContext *ua);
-static int is_legal_volume_name(UAContext *ua, char *name);
 static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, 
               POOL_DBR *pr, int relabel);
 static vol_list_t *get_slot_list_from_SD(UAContext *ua);
+static int is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr);
 
 
 /*
@@ -102,7 +102,7 @@ int update_slots(UAContext *ua)
             } else {
                bsendmsg(ua, _(
                   "Catalog record for Volume \"%s\" updated to reference slot %d.\n"),
-                 mr.Slot);
+                 mr.VolumeName, mr.Slot);
             }
          } else {
              bsendmsg(ua, _("Catalog record for Volume \"%s\" is up to date.\n"),
@@ -148,12 +148,6 @@ static int do_label(UAContext *ua, char *cmd, int relabel)
    int ok = FALSE;
    int mounted = FALSE;
    int i;
-   static char *name_keyword[] = {
-      "name",
-      NULL};
-   static char *vol_keyword[] = {
-      "volume",
-      NULL};
    static char *barcode_keyword[] = {
       "barcode",
       "barcodes",
@@ -178,8 +172,8 @@ static int do_label(UAContext *ua, char *cmd, int relabel)
    /* If relabel get name of Volume to relabel */
    if (relabel) {
       /* Check for volume=OldVolume */
-      i = find_arg_keyword(ua, vol_keyword); 
-      if (i >= 0 && ua->argv[i]) {
+      i = find_arg_with_value(ua, "volume"); 
+      if (i >= 0) {
         memset(&omr, 0, sizeof(omr));
         bstrncpy(omr.VolumeName, ua->argv[i], sizeof(omr.VolumeName));
         if (db_get_media_record(ua->jcr, ua->db, &omr)) {
@@ -188,7 +182,7 @@ static int do_label(UAContext *ua, char *cmd, int relabel)
          bsendmsg(ua, "%s", db_strerror(ua->db));
       }
       /* No keyword or Vol not found, ask user to select */
-      if (!select_pool_and_media_dbr(ua, &pr, &omr)) {
+      if (!select_media_dbr(ua, &omr)) {
         return 1;
       }
 
@@ -202,8 +196,8 @@ checkVol:
    }
 
    /* Check for name=NewVolume */
-   i = find_arg_keyword(ua, name_keyword);
-   if (i >=0 && ua->argv[i]) {
+   i = find_arg_with_value(ua, "name");
+   if (i >= 0) {
       pm_strcpy(&ua->cmd, ua->argv[i]);
       goto checkName;
    }
@@ -214,7 +208,7 @@ checkVol:
         return 1;
       }
 checkName:
-      if (!is_legal_volume_name(ua, ua->cmd)) {
+      if (!is_volume_name_legal(ua, ua->cmd)) {
         continue;
       }
 
@@ -230,17 +224,16 @@ checkName:
 
    /* If autochanger, request slot */
    if (store->autochanger) {
-      for ( ;; ) {
-         if (!get_cmd(ua, _("Enter slot (0 for none): "))) {
-           return 1;
-        }
-        mr.Slot = atoi(ua->cmd);
-        if (mr.Slot >= 0) {          /* OK */
-           break;
-        }
-         bsendmsg(ua, _("Slot numbers must be positive.\n"));
+      i = find_arg_with_value(ua, "slot"); 
+      if (i >= 0) {
+        mr.Slot = atoi(ua->argv[i]);
+      } else if (!get_pint(ua, _("Enter slot (0 for none): "))) {
+        return 1;
+      } else {
+        mr.Slot = ua->pint32_val;
       }
    }
+
    bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
 
    /* Must select Pool if not already done */
@@ -310,7 +303,6 @@ static void label_from_barcodes(UAContext *ua)
 
    vol_list = get_slot_list_from_SD(ua);
 
-
    if (!vol_list) {
       bsendmsg(ua, _("No Volumes found to label, or no barcodes.\n"));
       goto bail_out;
@@ -344,6 +336,20 @@ static void label_from_barcodes(UAContext *ua)
             vl->Slot, mr.VolumeName);
          continue;
       }
+      /*
+       * Deal with creating cleaning tape here. Normal tapes created in
+       *  send_label_request() below
+       */
+      if (is_cleaning_tape(ua, &mr, &pr)) {
+        set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
+        if (db_create_media_record(ua->jcr, ua->db, &mr)) {
+            bsendmsg(ua, _("Catalog record for cleaning tape \"%s\" successfully created.\n"),
+              mr.VolumeName);
+        } else {
+            bsendmsg(ua, "Catalog error on cleaning tape: %s", db_strerror(ua->db));
+        }
+        continue;
+      }
       bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
       if (ua->jcr->store_bsock) {
         bnet_sig(ua->jcr->store_bsock, BNET_TERMINATE);
@@ -381,21 +387,37 @@ bail_out:
    return;
 }
 
-static int is_legal_volume_name(UAContext *ua, char *name)
+/* 
+ * Check if the Volume name has legal characters
+ * If ua is non-NULL send the message
+ */
+int is_volume_name_legal(UAContext *ua, char *name)
 {
    int len;
+   char *p;
+   char *accept = ":.-_";
+
    /* Restrict the characters permitted in the Volume name */
-   if (strpbrk(name, "`~!@#$%^&*()[]{}|\\;'\"<>?,/")) {
-      bsendmsg(ua, _("Illegal character | in a volume name.\n"));
+   for (p=name; *p; p++) {
+      if (B_ISALPHA(*p) || B_ISDIGIT(*p) || strchr(accept, (int)(*p))) {
+        continue;
+      }
+      if (ua) {
+         bsendmsg(ua, _("Illegal character \"%c\" in a volume name.\n"), *p);
+      }
       return 0;
    }
    len = strlen(name);
    if (len >= MAX_NAME_LENGTH) {
-      bsendmsg(ua, _("Volume name too long.\n"));
+      if (ua) {
+         bsendmsg(ua, _("Volume name too long.\n"));
+      }
       return 0;
    }
    if (len == 0) {
-      bsendmsg(ua, _("Volume name must be at least one character long.\n"));
+      if (ua) {
+         bsendmsg(ua, _("Volume name must be at least one character long.\n"));
+      }
       return 0;
    }
    return 1;
@@ -423,12 +445,13 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    } else {
       bnet_fsend(sd, _("label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d"), 
         dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot);
-      bsendmsg(ua, _("Sending label command for Volume \"%s\" ...\n"), mr->VolumeName);
+      bsendmsg(ua, _("Sending label command for Volume \"%s\" Slot %d ...\n"), 
+        mr->VolumeName, mr->Slot);
       Dmsg5(200, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d\n", 
         dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot);
    }
 
-   while (bget_msg(sd, 0) >= 0) {
+   while (bnet_recv(sd) >= 0) {
       bsendmsg(ua, "%s", sd->msg);
       if (strncmp(sd->msg, "3000 OK label.", 14) == 0) {
         ok = TRUE;
@@ -441,8 +464,8 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    if (ok) {
       set_pool_dbr_defaults_in_media_dbr(mr, pr);
       if (db_create_media_record(ua->jcr, ua->db, mr)) {
-         bsendmsg(ua, _("Media record for Volume \"%s\" successfully created.\n"),
-           mr->VolumeName);
+         bsendmsg(ua, _("Catalog record for Volume \"%s\", Slot %d  successfully created.\n"),
+           mr->VolumeName, mr->Slot);
       } else {
          bsendmsg(ua, "%s", db_strerror(ua->db));
         ok = FALSE;
@@ -476,13 +499,13 @@ static vol_list_t *get_slot_list_from_SD(UAContext *ua)
    bnet_fsend(sd, _("autochanger list %s \n"), dev_name);
 
    /* Read and organize list of Volumes */
-   while (bget_msg(sd, 0) >= 0) {
+   while (bnet_recv(sd) >= 0) {
       char *p;
       int Slot;
       strip_trailing_junk(sd->msg);
 
       /* Check for returned SD messages */
-      if (sd->msg[0] == '3'     && sd->msg[1] == '9' &&         
+      if (sd->msg[0] == '3'     && B_ISDIGIT(sd->msg[1]) &&
          B_ISDIGIT(sd->msg[2]) && B_ISDIGIT(sd->msg[3]) &&
           sd->msg[4] == ' ') {
          bsendmsg(ua, "%s\n", sd->msg);   /* pass them on to user */
@@ -500,7 +523,7 @@ static vol_list_t *get_slot_list_from_SD(UAContext *ua)
         continue;
       }
       Slot = atoi(sd->msg);
-      if (Slot <= 0 || !is_legal_volume_name(ua, p)) {
+      if (Slot <= 0 || !is_volume_name_legal(ua, p)) {
         continue;
       }
 
@@ -524,3 +547,25 @@ static vol_list_t *get_slot_list_from_SD(UAContext *ua)
    }
    return vol_list;
 }
+
+/*
+ * Check if this is a cleaning tape by comparing the Volume name
+ *  with the Cleaning Prefix. If they match, this is a cleaning 
+ *  tape.
+ */
+static int is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr)
+{
+   if (!ua->jcr->pool) {
+      /* Find Pool resource */
+      ua->jcr->pool = (POOL *)GetResWithName(R_POOL, pr->Name);
+      if (!ua->jcr->pool) {
+         bsendmsg(ua, _("Pool %s resource not found!\n"), pr->Name);
+        return 1;
+      }
+   }
+   if (ua->jcr->pool->cleaning_prefix == NULL) {
+      return 0;
+   }
+   return strncmp(mr->VolumeName, ua->jcr->pool->cleaning_prefix,
+                 strlen(ua->jcr->pool->cleaning_prefix)) == 0;
+}