Fixed register spec so that colon isn't treated as size separator
[idzebra-moved-to-github.git] / bfile / mfile.c
index 6074cfb..342512f 100644 (file)
@@ -1,10 +1,23 @@
 /*
- * Copyright (C) 1994-1997, Index Data I/S 
+ * Copyright (C) 1994-1998, Index Data I/S 
  * All rights reserved.
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: mfile.c,v $
- * Revision 1.24  1997-09-17 12:19:06  adam
+ * Revision 1.28  1998-05-20 10:00:35  adam
+ * Fixed register spec so that colon isn't treated as size separator
+ * unless followed by [0-9+-] in order to allow DOS drive specifications.
+ *
+ * Revision 1.27  1998/02/10 11:55:07  adam
+ * Minor changes.
+ *
+ * Revision 1.26  1997/10/27 14:25:38  adam
+ * Fixed memory leaks.
+ *
+ * Revision 1.25  1997/09/18 08:59:16  adam
+ * Extra generic handle for the character mapping routines.
+ *
+ * Revision 1.24  1997/09/17 12:19:06  adam
  * Zebra version corresponds to YAZ version 1.4.
  * Changed Zebra server so that it doesn't depend on global common_resource.
  *
@@ -121,8 +134,10 @@ static int scan_areadef(MFile_area ma, const char *name, const char *ad)
             ad++;
         if (!*ad)
             break;
-        while (*ad && *ad != ':')
+        while (*ad)
         {
+           if (*ad == ':' && strchr ("+-0123456789", ad[1]))
+               break;
             if (i < FILENAME_MAX)
                 dirname[i++] = *ad;
             ad++;
@@ -224,7 +239,7 @@ static int cmp_part_file(const void *p1, const void *p2)
  */
 MFile_area mf_init(const char *name, const char *spec)
 {
-    MFile_area ma = xmalloc(sizeof(MFile_area_struct));
+    MFile_area ma = xmalloc(sizeof(*ma));
     mf_dir *dirp;
     meta_file *meta_f;
     part_file *part_f = 0;
@@ -232,9 +247,8 @@ MFile_area mf_init(const char *name, const char *spec)
     struct dirent *dent;
     int fd, number;
     char metaname[FILENAME_MAX+1], tmpnam[FILENAME_MAX+1];
-
+    
     logf (LOG_DEBUG, "mf_init(%s)", name);
-    ma = xmalloc(sizeof(MFile_area_struct));
     strcpy(ma->name, name);
     ma->mfiles = 0;
     ma->dirs = 0;
@@ -317,13 +331,43 @@ MFile_area mf_init(const char *name, const char *spec)
     return ma;
 }
 
+void mf_destroy(MFile_area ma)
+{
+    mf_dir *dp;
+    meta_file *meta_f;
+
+    if (!ma)
+       return;
+    dp = ma->dirs;
+    while (dp)
+    {
+       mf_dir *d = dp;
+       dp = dp->next;
+       xfree (d);
+    }
+    meta_f = ma->mfiles;
+    while (meta_f)
+    {
+       int i;
+       meta_file *m = meta_f;
+       
+       for (i = 0; i<m->no_files; i++)
+       {
+           xfree (m->files[i].path);
+       }
+       meta_f = meta_f->next;
+       xfree (m);
+    }
+    xfree (ma);
+}
+
 /*
  * Open a metafile.
  * If !ma, Use MF_DEFAULT_AREA.
  */
 MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag)
 {
-    struct meta_file *new;
+    struct meta_file *mnew;
     int i;
     char tmp[FILENAME_MAX+1];
     mf_dir *dp;
@@ -331,62 +375,65 @@ MFile mf_open(MFile_area ma, const char *name, int block_size, int wflag)
     logf(LOG_DEBUG, "mf_open(%s bs=%d, %s)", name, block_size,
          wflag ? "RW" : "RDONLY");
     assert (ma);
-    for (new = ma->mfiles; new; new = new->next)
-       if (!strcmp(name, new->name))
-           if (new->open)
+    for (mnew = ma->mfiles; mnew; mnew = mnew->next)
+       if (!strcmp(name, mnew->name))
+           if (mnew->open)
                abort();
            else
                break;
-    if (!new)
+    if (!mnew)
     {
-       new = xmalloc(sizeof(*new));
-       strcpy(new->name, name);
+       mnew = xmalloc(sizeof(*mnew));
+       strcpy(mnew->name, name);
        /* allocate one, empty file */
-       new->no_files = 1;
-       new->files[0].bytes = new->files[0].blocks = 0;
-       new->files[0].top = -1;
-       new->files[0].number = 0;
-       new->files[0].fd = -1;
-       new->min_bytes_creat = MF_MIN_BLOCKS_CREAT * block_size;
+       mnew->no_files = 1;
+       mnew->files[0].bytes = mnew->files[0].blocks = 0;
+       mnew->files[0].top = -1;
+       mnew->files[0].number = 0;
+       mnew->files[0].fd = -1;
+       mnew->min_bytes_creat = MF_MIN_BLOCKS_CREAT * block_size;
        for (dp = ma->dirs; dp && dp->max_bytes >= 0 && dp->avail_bytes <
-           new->min_bytes_creat; dp = dp->next);
+           mnew->min_bytes_creat; dp = dp->next);
        if (!dp)
        {
            logf (LOG_FATAL, "Insufficient space for new mfile.");
            return 0;
        }
-       new->files[0].dir = dp;
-       sprintf(tmp, "%s/%s.mf.%d", dp->name, new->name, 0);
-       new->files[0].path = xstrdup(tmp);
-       new->ma = ma;
+       mnew->files[0].dir = dp;
+       sprintf(tmp, "%s/%s.mf.%d", dp->name, mnew->name, 0);
+       mnew->files[0].path = xstrdup(tmp);
+       mnew->ma = ma;
+       mnew->next = ma->mfiles;
+       ma->mfiles = mnew;
     }
     else
     {
-       for (i = 0; i < new->no_files; i++)
+       for (i = 0; i < mnew->no_files; i++)
        {
-           if (new->files[i].bytes % block_size)
-               new->files[i].bytes += block_size - new->files[i].bytes %
+           if (mnew->files[i].bytes % block_size)
+               mnew->files[i].bytes += block_size - mnew->files[i].bytes %
                    block_size;
-           new->files[i].blocks = new->files[i].bytes / block_size;
+           mnew->files[i].blocks = mnew->files[i].bytes / block_size;
        }
-       assert(!new->open);
+       assert(!mnew->open);
     }
-    new->blocksize = block_size;
-    new->min_bytes_creat = MF_MIN_BLOCKS_CREAT * block_size;
-    new->wr=wflag;
-    new->cur_file = 0;
-    new->open = 1;
+    mnew->blocksize = block_size;
+    mnew->min_bytes_creat = MF_MIN_BLOCKS_CREAT * block_size;
+    mnew->wr=wflag;
+    mnew->cur_file = 0;
+    mnew->open = 1;
 
-    for (i = 0; i < new->no_files; i++)
+    for (i = 0; i < mnew->no_files; i++)
     {
-       new->files[i].blocks = new->files[i].bytes / new->blocksize;
-       if (i == new->no_files - 1)
-           new->files[i].top = -1;
+       mnew->files[i].blocks = mnew->files[i].bytes / mnew->blocksize;
+       if (i == mnew->no_files - 1)
+           mnew->files[i].top = -1;
        else
-           new->files[i].top = i ? (new->files[i-1].top + new->files[i].blocks)
-               : (new->files[i].blocks - 1);
+           mnew->files[i].top =
+               i ? (mnew->files[i-1].top + mnew->files[i].blocks)
+               : (mnew->files[i].blocks - 1);
     }
-    return new;
+    return mnew;
 }
 
 /*
@@ -514,7 +561,8 @@ int mf_write(MFile mf, int no, int offset, int num, const void *buf)
     towrite = num ? num : mf->blocksize;
     if (write(mf->files[mf->cur_file].fd, buf, towrite) < towrite)
     {
-       logf (LOG_FATAL|LOG_ERRNO, "Write failed");
+       logf (LOG_FATAL|LOG_ERRNO, "Write failed for file %s part %d",
+               mf->name, mf->cur_file);
        exit(1);
     }
     return 0;