]> git.sur5r.net Git - bacula/bacula/commitdiff
- Add drive specification to mount, unmount, release, label,
authorKern Sibbald <kern@sibbald.com>
Sat, 13 Aug 2005 15:22:33 +0000 (15:22 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 13 Aug 2005 15:22:33 +0000 (15:22 +0000)
  and relabel for Autochangers.  Note Dir<->SD protocol has
  changed.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2311 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/kernstodo
bacula/kes-1.37
bacula/src/dird/protos.h
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_label.c
bacula/src/dird/ua_select.c
bacula/src/stored/dircmd.c
bacula/src/version.h

index 5efb120c1553b198ecdd4c2306f3b1bce0dd39d1..f89e82461bb3e8094c87f9f84c8ed6c054f10e71 100644 (file)
@@ -28,37 +28,6 @@ Document:
 - Pruning with Admin job.
 - Restore of all files for a Job or set of jobs even if the file
   records have been removed from the catalog.
-========= probably not in 1.38 =============
-   - MaximumPartSize = bytes (SD, Device resource)
-     Defines the maximum part size.
-   - Requires Mount = Yes/No (SD, Device resource)
-     Defines if the device require to be mounted to be read, and if it
-     must be written in a special way. If it set, the following directives
-     must be defined in the same Device resource:
-     + Mount Point = directory
-       Directory where the device must be mounted.
-     + Mount Command = name-string
-       Command that must be executed to mount the device. Before the command
-       is executed, %a is replaced with the Archive Device, and %m with the
-       Mount Point.
-     + Unmount Command = name-string
-       Command that must be executed to unmount the device. Before the
-       command is executed, %a is replaced with the Archive Device, and
-       %m with the Mount Point.
-     + Write Part Command = name-string
-       Command that must be executed to write a part to the device. Before
-       the command is executed, %a is replaced with the Archive Device, %m
-       with the Mount Point, %n with the current part number (0-based),
-       and %v with the current part filename.
-     + Free Space Command = name-string
-       Command that must be executed to check how much free space is left
-       on the device. Before the command is executed, %a is replaced with
-       the Archive Device, %m with the Mount Point, %n with the current part
-       number (0-based), and %v with the current part filename.
-   - Write Part After Job = Yes/No (DIR, Job Resource, and Schedule Resource)
-     If this directive is set to yes (default no), a new part file will be
-     created after the job is finished.
-=======
 
 For 1.39:
 - Look at NDMP
index a91b554111b47f81a9531138f913725a8109e722..c1e16ae882df07713380eb4520a2f523091b16b6 100644 (file)
@@ -3,6 +3,12 @@
 
 General:
 
+Changes to 1.37.36:
+13Aug05
+- Add drive specification to mount, unmount, release, label,
+  and relabel for Autochangers.  Note Dir<->SD protocol has
+  changed.
+
 Changes to 1.37.35:
 12Aug05
 - Disable parts of NLS as the configure does not work here.
index 0d983686faa5f8de66865e4e4b9a95dd34ab39fc..b6a3513de2f923dba906b6e82eecceb00f9b55fd 100644 (file)
@@ -186,7 +186,7 @@ void    start_prompt(UAContext *ua, const char *msg);
 void    add_prompt(UAContext *ua, const char *prompt);
 int     do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt);
 CAT    *get_catalog_resource(UAContext *ua);
-STORE  *get_storage_resource(UAContext *ua, int use_default);
+STORE  *get_storage_resource(UAContext *ua, bool use_default);
 int     get_media_type(UAContext *ua, char *MediaType, int max_media);
 bool    get_pool_dbr(UAContext *ua, POOL_DBR *pr);
 int     get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
index 04f8672e7825c9a499367db855491404689f0a9d..692a7b69ed2b639c787d990c3c494a213b93e571 100644 (file)
@@ -222,7 +222,7 @@ static int add_cmd(UAContext *ua, const char *cmd)
    }
 
    /* Get media type */
-   if ((store = get_storage_resource(ua, 0)) != NULL) {
+   if ((store = get_storage_resource(ua, false/*no default*/)) != NULL) {
       bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
    } else if (!get_media_type(ua, mr.MediaType, sizeof(mr.MediaType))) {
       return 1;
@@ -813,7 +813,7 @@ static int setdebug_cmd(UAContext *ua, const char *cmd)
                return 1;
             }
          }
-         store = get_storage_resource(ua, 0);
+         store = get_storage_resource(ua, false/*no default*/);
          if (store) {
             do_storage_setdebug(ua, store, level, trace_flag);
             return 1;
@@ -835,7 +835,7 @@ static int setdebug_cmd(UAContext *ua, const char *cmd)
       set_trace(trace_flag);
       break;
    case 1:
-      store = get_storage_resource(ua, 0);
+      store = get_storage_resource(ua, false/*no default*/);
       if (store) {
          do_storage_setdebug(ua, store, level, trace_flag);
       }
@@ -1246,19 +1246,21 @@ static void do_mount_cmd(UAContext *ua, const char *command)
    BSOCK *sd;
    JCR *jcr = ua->jcr;
    char dev_name[MAX_NAME_LENGTH];
+   int drive;
 
    if (!open_db(ua)) {
       return;
    }
    Dmsg2(120, "%s: %s\n", command, ua->UA_sock->msg);
 
-   store = get_storage_resource(ua, 1);
+   store = get_storage_resource(ua, true/*use default*/);
    if (!store) {
       return;
    }
+   drive = ua->int32_val;
 
-   Dmsg2(120, "Found storage, MediaType=%s DevName=%s\n",
-      store->media_type, store->dev_name());
+   Dmsg3(120, "Found storage, MediaType=%s DevName=%s drive=%d\n",
+      store->media_type, store->dev_name(), drive);
 
    set_storage(jcr, store);
    if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
@@ -1268,7 +1270,7 @@ static void do_mount_cmd(UAContext *ua, const char *command)
    sd = jcr->store_bsock;
    bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
    bash_spaces(dev_name);
-   bnet_fsend(sd, "%s %s", command, dev_name);
+   bnet_fsend(sd, "%s %s drive=%d", command, dev_name, drive);
    while (bnet_recv(sd) >= 0) {
       bsendmsg(ua, "%s", sd->msg);
    }
@@ -1278,7 +1280,7 @@ static void do_mount_cmd(UAContext *ua, const char *command)
 }
 
 /*
- * mount [storage | device] <name>
+ * mount [storage=<name>] [drive=nn]
  */
 static int mount_cmd(UAContext *ua, const char *cmd)
 {
@@ -1288,7 +1290,7 @@ static int mount_cmd(UAContext *ua, const char *cmd)
 
 
 /*
- * unmount [storage | device] <name>
+ * unmount [storage=<name>] [drive=nn]
  */
 static int unmount_cmd(UAContext *ua, const char *cmd)
 {
@@ -1298,7 +1300,7 @@ static int unmount_cmd(UAContext *ua, const char *cmd)
 
 
 /*
- * release [storage | device] <name>
+ * release [storage=<name>] [drive=nn]
  */
 static int release_cmd(UAContext *ua, const char *cmd)
 {
index 408f04f5406574966983cea31f6e41242757d309..41e6a6ed08d70054efb7a9a45cee1ac920b3265d 100644 (file)
@@ -34,15 +34,15 @@ typedef struct s_vol_list {
 
 /* Forward referenced functions */
 static int do_label(UAContext *ua, const char *cmd, int relabel);
-static void label_from_barcodes(UAContext *ua);
+static void label_from_barcodes(UAContext *ua, int drive);
 static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
-               POOL_DBR *pr, int relabel, bool media_record_exits);
+               POOL_DBR *pr, int relabel, bool media_record_exits, int drive);
 static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan);
 static void free_vol_list(vol_list_t *vol_list);
 static bool is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr);
 static BSOCK *open_sd_bsock(UAContext *ua);
 static void close_sd_bsock(UAContext *ua);
-static char *get_volume_name_from_SD(UAContext *ua, int Slot);
+static char *get_volume_name_from_SD(UAContext *ua, int Slot, int drive);
 static int get_num_slots_from_SD(UAContext *ua);
 
 
@@ -156,6 +156,7 @@ int update_slots(UAContext *ua)
    char *slot_list;
    bool scan;
    int max_slots;
+   int drive = -1;
 
 
    if (!open_db(ua)) {
@@ -205,7 +206,7 @@ int update_slots(UAContext *ua)
             free(vl->VolName);
             vl->VolName = NULL;
          }
-         vl->VolName = get_volume_name_from_SD(ua, vl->Slot);
+         vl->VolName = get_volume_name_from_SD(ua, vl->Slot, drive);
          Dmsg2(100, "Got Vol=%s from SD for Slot=%d\n", vl->VolName, vl->Slot);
       }
       slot_list[vl->Slot] = 0;        /* clear Slot */
@@ -285,6 +286,7 @@ static int do_label(UAContext *ua, const char *cmd, int relabel)
    bool print_reminder = true;
    int ok = FALSE;
    int i;
+   int drive;
    bool media_record_exists = false;
    static const char *barcode_keyword[] = {
       "barcode",
@@ -296,14 +298,15 @@ static int do_label(UAContext *ua, const char *cmd, int relabel)
    if (!open_db(ua)) {
       return 1;
    }
-   store = get_storage_resource(ua, 1);
+   store = get_storage_resource(ua, true/*use default*/);
    if (!store) {
       return 1;
    }
+   drive = ua->int32_val;
    set_storage(ua->jcr, store);
 
    if (!relabel && find_arg_keyword(ua, barcode_keyword) >= 0) {
-      label_from_barcodes(ua);
+      label_from_barcodes(ua, drive);
       return 1;
    }
 
@@ -389,7 +392,7 @@ checkName:
       }
    }
 
-   ok = send_label_request(ua, &mr, &omr, &pr, relabel, media_record_exists);
+   ok = send_label_request(ua, &mr, &omr, &pr, relabel, media_record_exists, drive);
 
    if (ok) {
       sd = ua->jcr->store_bsock;
@@ -412,7 +415,7 @@ checkName:
          bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
          bsendmsg(ua, _("Requesting to mount %s ...\n"), dev_name);
          bash_spaces(dev_name);
-         bnet_fsend(sd, "mount %s", dev_name);
+         bnet_fsend(sd, "mount %s drive=%d", dev_name, drive);
          unbash_spaces(dev_name);
          while (bnet_recv(sd) >= 0) {
             bsendmsg(ua, "%s", sd->msg);
@@ -443,7 +446,7 @@ checkName:
  * Request SD to send us the slot:barcodes, then wiffle
  *  through them all labeling them.
  */
-static void label_from_barcodes(UAContext *ua)
+static void label_from_barcodes(UAContext *ua, int drive)
 {
    STORE *store = ua->jcr->store;
    POOL_DBR pr;
@@ -548,7 +551,7 @@ static void label_from_barcodes(UAContext *ua)
       bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType));
 
       mr.Slot = vl->Slot;
-      send_label_request(ua, &mr, &omr, &pr, 0, media_record_exists);
+      send_label_request(ua, &mr, &omr, &pr, 0, media_record_exists, drive);
    }
 
 
@@ -600,7 +603,8 @@ bool is_volume_name_legal(UAContext *ua, const char *name)
  * NOTE! This routine opens the SD socket but leaves it open
  */
 static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
-                               POOL_DBR *pr, int relabel, bool media_record_exists)
+                               POOL_DBR *pr, int relabel, bool media_record_exists,
+                               int drive)
 {
    BSOCK *sd;
    char dev_name[MAX_NAME_LENGTH];
@@ -616,17 +620,21 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    bash_spaces(pr->Name);
    if (relabel) {
       bash_spaces(omr->VolumeName);
-      bnet_fsend(sd, "relabel %s OldName=%s NewName=%s PoolName=%s MediaType=%s Slot=%d",
-         dev_name, omr->VolumeName, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot);
+      bnet_fsend(sd, "relabel %s OldName=%s NewName=%s PoolName=%s "
+                     "MediaType=%s Slot=%d drive=%d",
+                 dev_name, omr->VolumeName, mr->VolumeName, pr->Name, 
+                 mr->MediaType, mr->Slot, drive);
       bsendmsg(ua, _("Sending relabel command from \"%s\" to \"%s\" ...\n"),
          omr->VolumeName, mr->VolumeName);
    } else {
-      bnet_fsend(sd, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d",
-         dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot);
+      bnet_fsend(sd, "label %s VolumeName=%s PoolName=%s MediaType=%s "
+                     "Slot=%d drive=%d",
+                 dev_name, mr->VolumeName, pr->Name, mr->MediaType, 
+                 mr->Slot, drive);
       bsendmsg(ua, _("Sending label command for Volume \"%s\" Slot %d ...\n"),
          mr->VolumeName, mr->Slot);
-      Dmsg5(100, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d\n",
-         dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot);
+      Dmsg6(100, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d drive=%d\n",
+         dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot, drive);
    }
 
    while (bnet_recv(sd) >= 0) {
@@ -695,7 +703,7 @@ static void close_sd_bsock(UAContext *ua)
    }
 }
 
-static char *get_volume_name_from_SD(UAContext *ua, int Slot)
+static char *get_volume_name_from_SD(UAContext *ua, int Slot, int drive)
 {
    STORE *store = ua->jcr->store;
    BSOCK *sd;
@@ -710,7 +718,7 @@ static char *get_volume_name_from_SD(UAContext *ua, int Slot)
    bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
    bash_spaces(dev_name);
    /* Ask for autochanger list of volumes */
-   bnet_fsend(sd, _("readlabel %s Slot=%d\n"), dev_name, Slot);
+   bnet_fsend(sd, _("readlabel %s Slot=%d drive=%d\n"), dev_name, Slot, drive);
    Dmsg1(100, "Sent: %s", sd->msg);
 
    /* Get Volume name in this Slot */
index 5409ee49b32463f0b03ea2e413edbec341a96a21..2b576d5f34236026f4456237cca0ed6364c58447 100644 (file)
@@ -756,7 +756,7 @@ done:
  * If use_default is set, we assume that any keyword without a value
  *   is the name of the Storage resource wanted.
  */
-STORE *get_storage_resource(UAContext *ua, int use_default)
+STORE *get_storage_resource(UAContext *ua, bool use_default)
 {
    char *store_name = NULL;
    STORE *store = NULL;
@@ -765,13 +765,16 @@ STORE *get_storage_resource(UAContext *ua, int use_default)
    int i;
    char ed1[50];
 
-
+   ua->int32_val = -2;   /* dummy */
    for (i=1; i<ua->argc; i++) {
+      if (strcasecmp("drive", ua->argk[i]) == 0 && ua->argv[i]) {
+         ua->int32_val = atoi(ua->argv[i]);
+      }
       if (use_default && !ua->argv[i]) {
          /* Ignore slots, scan and barcode(s) keywords */
-         if (strncasecmp("scan", ua->argk[i], 4) == 0 ||
-             strncasecmp("barcode", ua->argk[i], 7) == 0 ||
-             strncasecmp("slots", ua->argk[i], 5) == 0) {
+         if (strcasecmp("scan", ua->argk[i]) == 0 ||
+             strcasecmp("barcode", ua->argk[i]) == 0 ||
+             strcasecmp("slots", ua->argk[i]) == 0) {
             continue;
          }
          /* Default argument is storage */
@@ -836,6 +839,15 @@ STORE *get_storage_resource(UAContext *ua, int use_default)
    if (!store) {
       store = select_storage_resource(ua);
    }
+   /* Get drive for autochanger if possible */
+   if (store && store->autochanger && ua->int32_val == -2) {
+      ua->cmd[0] = 0;
+      if (!get_cmd(ua, _("Enter autochanger drive [0]: "))) {
+         ua->int32_val = -1;  /* None */
+      } else {
+         ua->int32_val = atoi(ua->cmd);
+      }
+   }
    return store;
 }
 
index 9166d1fd6eb5471cda2b02bf37df7b56a9a091e5..7f40b79971b31651921bb6478d37d0fccf0e9a7d 100644 (file)
@@ -73,7 +73,7 @@ static bool mount_cmd(JCR *jcr);
 static bool unmount_cmd(JCR *jcr);
 static bool autochanger_cmd(JCR *sjcr);
 static bool do_label(JCR *jcr, int relabel);
-static DEVICE *find_device(JCR *jcr, POOL_MEM &dev_name);
+static DEVICE *find_device(JCR *jcr, POOL_MEM &dev_name, int drive);
 static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot);
 static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
                                char *newname, char *poolname,
@@ -308,20 +308,24 @@ static bool do_label(JCR *jcr, int relabel)
    DEVICE *dev;
    bool ok = false;
    int slot;
+   int drive;
 
    newname = get_memory(dir->msglen+1);
    oldname = get_memory(dir->msglen+1);
    poolname = get_memory(dir->msglen+1);
    mtype = get_memory(dir->msglen+1);
    if (relabel) {
-      if (sscanf(dir->msg, "relabel %127s OldName=%127s NewName=%127s PoolName=%127s MediaType=%127s Slot=%d",
-          dev_name.c_str(), oldname, newname, poolname, mtype, &slot) == 6) {
+      if (sscanf(dir->msg, "relabel %127s OldName=%127s NewName=%127s PoolName=%127s "
+                 "MediaType=%127s Slot=%d drive=%d",
+                  dev_name.c_str(), oldname, newname, poolname, mtype, 
+                  &slot, &drive) == 7) {
          ok = true;
       }
    } else {
       *oldname = 0;
-      if (sscanf(dir->msg, "label %127s VolumeName=%127s PoolName=%127s MediaType=%127s Slot=%d",
-          dev_name.c_str(), newname, poolname, mtype, &slot) == 5) {
+      if (sscanf(dir->msg, "label %127s VolumeName=%127s PoolName=%127s "
+                 "MediaType=%127s Slot=%d drive=%d", 
+          dev_name.c_str(), newname, poolname, mtype, &slot, &drive) == 6) {
          ok = true;
       }
    }
@@ -330,7 +334,7 @@ static bool do_label(JCR *jcr, int relabel)
       unbash_spaces(oldname);
       unbash_spaces(poolname);
       unbash_spaces(mtype);
-      dev = find_device(jcr, dev_name);
+      dev = find_device(jcr, dev_name, drive);
       if (dev) {
          P(dev->mutex);               /* Use P to avoid indefinite block */
          if (!dev->is_open()) {
@@ -474,7 +478,7 @@ static bool read_label(DCR *dcr)
    return ok;
 }
 
-static DEVICE *find_device(JCR *jcr, POOL_MEM &devname)
+static DEVICE *find_device(JCR *jcr, POOL_MEM &devname, int drive)
 {
    DEVRES *device;
    AUTOCHANGER *changer;
@@ -517,9 +521,11 @@ static DEVICE *find_device(JCR *jcr, POOL_MEM &devname)
             if (!device->dev->autoselect) {
                continue;              /* device is not available */
             }
-            Dmsg1(20, "Found changer device %s\n", device->hdr.name);
-            found = true;
-            break;
+            if (drive < 0 || drive == (int)device->dev->drive_index) {
+               Dmsg1(20, "Found changer device %s\n", device->hdr.name);
+               found = true;
+               break;
+            }
          }
          break;                    /* we found it but could not open a device */
       }
@@ -543,9 +549,10 @@ static bool mount_cmd(JCR *jcr)
    BSOCK *dir = jcr->dir_bsock;
    DEVICE *dev;
    DCR *dcr;
+   int drive;
 
-   if (sscanf(dir->msg, "mount %127s", devname.c_str()) == 1) {
-      dev = find_device(jcr, devname);
+   if (sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2) {
+      dev = find_device(jcr, devname, drive);
       dcr = jcr->dcr;
       if (dev) {
          P(dev->mutex);               /* Use P to avoid indefinite block */
@@ -663,9 +670,10 @@ static bool unmount_cmd(JCR *jcr)
    POOL_MEM devname;
    BSOCK *dir = jcr->dir_bsock;
    DEVICE *dev;
+   int drive;
 
-   if (sscanf(dir->msg, "unmount %127s", devname.c_str()) == 1) {
-      dev = find_device(jcr, devname);
+   if (sscanf(dir->msg, "unmount %127s drive=%d", devname.c_str(), &drive) == 2) {
+      dev = find_device(jcr, devname, drive);
       if (dev) {
          P(dev->mutex);               /* Use P to avoid indefinite block */
          if (!dev->is_open()) {
@@ -732,9 +740,10 @@ static bool release_cmd(JCR *jcr)
    POOL_MEM devname;
    BSOCK *dir = jcr->dir_bsock;
    DEVICE *dev;
+   int drive;
 
-   if (sscanf(dir->msg, "release %127s", devname.c_str()) == 1) {
-      dev = find_device(jcr, devname);
+   if (sscanf(dir->msg, "release %127s drive=%d", devname.c_str(), &drive) == 2) {
+      dev = find_device(jcr, devname, drive);
       if (dev) {
          P(dev->mutex);               /* Use P to avoid indefinite block */
          if (!dev->is_open()) {
@@ -800,17 +809,15 @@ static bool autochanger_cmd(JCR *jcr)
       ok = true;
    }
    if (ok) {
-      dev = find_device(jcr, devname);
+      dev = find_device(jcr, devname, -1);
       dcr = jcr->dcr;
       if (dev) {
          P(dev->mutex);               /* Use P to avoid indefinite block */
          if (!dev->is_tape()) {
             bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"), 
                dev->print_name());
-         } else if (!dev->is_open()) {
-            autochanger_cmd(dcr, dir, cmd);
          /* Under certain "safe" conditions, we can steal the lock */
-         } else if (dev->can_steal_lock()) {
+         } else if (!dev->is_open() || dev->can_steal_lock()) {
             autochanger_cmd(dcr, dir, cmd);
          } else if (dev->is_busy() || dev->is_blocked()) {
             send_dir_busy_message(dir, dev);
@@ -839,9 +846,11 @@ static bool readlabel_cmd(JCR *jcr)
    BSOCK *dir = jcr->dir_bsock;
    DEVICE *dev;
    int Slot;
+   int drive;
 
-   if (sscanf(dir->msg, "readlabel %127s Slot=%d", devname.c_str(), &Slot) == 2) {
-      dev = find_device(jcr, devname);
+   if (sscanf(dir->msg, "readlabel %127s Slot=%d drive=%d", devname.c_str(), 
+       &Slot, &drive) == 3) {
+      dev = find_device(jcr, devname, drive);
       if (dev) {
          P(dev->mutex);               /* Use P to avoid indefinite block */
          if (!dev->is_open()) {
index 619d25ca99b6861d273a6b8b486a708789c0e956..c01e52562bb2671d0ea91800cf305da40402720d 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #undef  VERSION
-#define VERSION "1.37.35"
-#define BDATE   "12 August 2005"
-#define LSMDATE "12Aug05"
+#define VERSION "1.37.36"
+#define BDATE   "13 August 2005"
+#define LSMDATE "13Aug05"
 
 /* Debug flags */
 #undef  DEBUG