* Sebastian Hammer, Adam Dickmeiss
*
* $Log: mfile.c,v $
- * Revision 1.34 1999-05-26 07:49:12 adam
+ * Revision 1.43 2002-04-04 20:50:36 adam
+ * Multi register works with record paths and data1 profile path
+ *
+ * Revision 1.42 2002/04/04 14:14:13 adam
+ * Multiple registers (alpha early)
+ *
+ * Revision 1.41 2000/11/29 14:24:01 adam
+ * Script configure uses yaz pthreads options. Added locking for
+ * zebra_register_{lock,unlock}.
+ *
+ * Revision 1.40 2000/10/17 12:37:09 adam
+ * Fixed notification of live-updates. Fixed minor problem with mf_init
+ * where it didn't handle shadow area file names correctly.
+ *
+ * Revision 1.39 2000/05/05 13:48:03 adam
+ * Fixed locking for metafiles.
+ *
+ * Revision 1.38 2000/03/20 19:08:35 adam
+ * Added remote record import using Z39.50 extended services and Segment
+ * Requests.
+ *
+ * Revision 1.37 2000/03/15 15:00:30 adam
+ * First work on threaded version.
+ *
+ * Revision 1.36 1999/12/08 15:03:11 adam
+ * Implemented bf_reset.
+ *
+ * Revision 1.35 1999/10/14 14:33:50 adam
+ * Added truncation 5=106.
+ *
+ * Revision 1.34 1999/05/26 07:49:12 adam
* C++ compilation.
*
* Revision 1.33 1999/05/12 13:08:06 adam
#include <assert.h>
#include <errno.h>
+#include <zebra-lock.h>
#include <zebrautl.h>
#include <mfile.h>
-static int scan_areadef(MFile_area ma, const char *name, const char *ad)
+static int scan_areadef(MFile_area ma, const char *ad, const char *base)
{
/*
* If no definition is given, use current directory, unlimited.
mf_dir **dp = &ma->dirs, *dir = *dp;
if (!ad)
- ad = ".:-1b";
+ ad = ".:-1b";
for (;;)
{
const char *ad0 = ad;
- int i = 0, fact = 1, multi, size = 0;
+ int i = 0, fact = 1, multi;
+ off_t size = 0;
while (*ad == ' ' || *ad == '\t')
ad++;
if (!*ad)
break;
+ if (!yaz_is_abspath(ad) && base)
+ {
+ strcpy (dirname, base);
+ i = strlen(dirname);
+ dirname[i++] = '/';
+ }
while (*ad)
{
if (*ad == ':' && strchr ("+-0123456789", ad[1]))
dirname[i] = '\0';
if (*ad++ != ':')
{
- logf (LOG_FATAL, "Missing colon after path: %s", ad0);
+ logf (LOG_WARN, "Missing colon after path: %s", ad0);
return -1;
}
if (i == 0)
{
- logf (LOG_FATAL, "Empty path: %s", ad0);
+ logf (LOG_WARN, "Empty path: %s", ad0);
return -1;
}
while (*ad == ' ' || *ad == '\t')
size = size*10 + (*ad++ - '0');
switch (*ad)
{
- case 'B': case 'b': multi = 1; break;
- case 'K': case 'k': multi = 1024; break;
- case 'M': case 'm': multi = 1048576; break;
+ case 'B': case 'b': multi = 1; break;
+ case 'K': case 'k': multi = 1024; break;
+ case 'M': case 'm': multi = 1048576; break;
+ case 'G': case 'g': multi = 1073741824; break;
case '\0':
logf (LOG_FATAL, "Missing unit: %s", ad0);
return -1;
{
if (!mf->wr && errno == ENOENT && off == 0)
return -2;
- logf (LOG_FATAL|LOG_ERRNO, "Failed to open %s", mf->files[c].path);
+ logf (LOG_WARN|LOG_ERRNO, "Failed to open %s", mf->files[c].path);
return -1;
}
if (lseek(mf->files[c].fd, (ps = pos - off) * mf->blocksize + offset,
SEEK_SET) < 0)
{
- logf (LOG_FATAL|LOG_ERRNO, "Failed to seek in %s", mf->files[c].path);
+ logf (LOG_WARN|LOG_ERRNO, "Failed to seek in %s", mf->files[c].path);
return -1;
}
mf->cur_file = c;
* Create a new area, cotaining metafiles in directories.
* Find the part-files in each directory, and inventory the existing metafiles.
*/
-MFile_area mf_init(const char *name, const char *spec)
+MFile_area mf_init(const char *name, const char *spec, const char *base)
{
MFile_area ma = (MFile_area) xmalloc(sizeof(*ma));
mf_dir *dirp;
strcpy(ma->name, name);
ma->mfiles = 0;
ma->dirs = 0;
- if (scan_areadef(ma, name, spec) < 0)
+ if (scan_areadef(ma, spec, base) < 0)
{
- logf (LOG_FATAL, "Failed to access description of '%s'", name);
+ logf (LOG_WARN, "Failed to access description of '%s'", name);
return 0;
}
/* look at each directory */
{
if (!(dd = opendir(dirp->name)))
{
- logf (LOG_FATAL|LOG_ERRNO, "Failed to open %s", dirp->name);
+ logf (LOG_WARN|LOG_ERRNO, "Failed to open directory %s",
+ dirp->name);
return 0;
}
/* look at each file */
while ((dent = readdir(dd)))
{
- if (*dent->d_name == '.')
- continue;
- if (sscanf(dent->d_name, "%[^-]-%d.mf", metaname, &number) != 2)
- {
- logf (LOG_DEBUG, "bf: %s is not a part-file.", dent->d_name);
- continue;
- }
+ int len = strlen(dent->d_name);
+ const char *cp = strrchr (dent->d_name, '-');
+ if (strchr (".-", *dent->d_name))
+ continue;
+ if (len < 5 || !cp || strcmp (dent->d_name + len - 3, ".mf"))
+ continue;
+ number = atoi(cp+1);
+ memcpy (metaname, dent->d_name, cp - dent->d_name);
+ metaname[ cp - dent->d_name] = '\0';
+
for (meta_f = ma->mfiles; meta_f; meta_f = meta_f->next)
{
/* known metafile */
if (!meta_f)
{
meta_f = (meta_file *) xmalloc(sizeof(*meta_f));
+ zebra_mutex_init (&meta_f->mutex);
meta_f->ma = ma;
meta_f->next = ma->mfiles;
meta_f->open = 0;
{
xfree (m->files[i].path);
}
+ zebra_mutex_destroy (&meta_f->mutex);
meta_f = meta_f->next;
xfree (m);
}
xfree (ma);
}
+void mf_reset(MFile_area ma)
+{
+ meta_file *meta_f;
+
+ if (!ma)
+ return;
+ meta_f = ma->mfiles;
+ while (meta_f)
+ {
+ int i;
+ meta_file *m = meta_f;
+
+ assert (!m->open);
+ for (i = 0; i<m->no_files; i++)
+ {
+ unlink (m->files[i].path);
+ xfree (m->files[i].path);
+ }
+ meta_f = meta_f->next;
+ xfree (m);
+ }
+ ma->mfiles = 0;
+}
+
/*
* Open a metafile.
* If !ma, Use MF_DEFAULT_AREA.
mnew = (meta_file *) xmalloc(sizeof(*mnew));
strcpy(mnew->name, name);
/* allocate one, empty file */
+ zebra_mutex_init (&mnew->mutex);
mnew->no_files = 1;
- mnew->files[0].bytes = mnew->files[0].blocks = 0;
+ mnew->files[0].bytes = 0;
+ mnew->files[0].blocks = 0;
mnew->files[0].top = -1;
mnew->files[0].number = 0;
mnew->files[0].fd = -1;
{
int rd, toread;
+ zebra_mutex_lock (&mf->mutex);
if ((rd = file_position(mf, no, offset)) < 0)
{
if (rd == -2)
+ {
+ zebra_mutex_unlock (&mf->mutex);
return 0;
+ }
else
exit(1);
}
mf->files[mf->cur_file].path);
exit(1);
}
- else if (rd < toread)
+ zebra_mutex_unlock (&mf->mutex);
+ if (rd < toread)
return 0;
else
return 1;
char tmp[FILENAME_MAX+1];
unsigned char dummych = '\xff';
+ zebra_mutex_lock (&mf->mutex);
if ((ps = file_position(mf, no, offset)) < 0)
exit(1);
/* file needs to grow */
mf->name, mf->cur_file);
exit(1);
}
+ zebra_mutex_unlock (&mf->mutex);
return 0;
}