2
* ===========================================================================
5
* National Center for Biotechnology Information
7
* This software/database is a "United States Government Work" under the
8
* terms of the United States Copyright Act. It was written as part of
9
* the author's official duties as a Government employee and thus cannot
10
* be copyrighted. This software/database is freely available to the
11
* public for use without a copyright notice. Restrictions cannot be
12
* placed on its present or future use.
14
* Although all reasonable efforts have been taken to ensure the accuracy
15
* and reliability of the software and data, the National Library of
16
* Medicine (NLM) and the U. S. Government do not and cannot warrant the
17
* performance or results that may be obtained by using this software or
18
* data. The NLM and the U. S. Government disclaim all warranties as to
19
* performance, merchantability or fitness for any particular purpose.
21
* Please see that the author is suitably cited in any work or product
22
* based on this material.
24
* ===========================================================================
26
* RCS $Id: cdconfig.c,v 6.1 1998/12/04 23:35:07 kans Exp $
28
* Author: Jonathan Epstein
30
* Version Creation Date: 11-92
33
* Complex configuration mechanism used in conjunction with the low-level
34
* data access library for the Molecular Sequence Data CD-ROM library produced
38
* --------------------------------------------------------------------------
39
* Rev Date Name Description of modification
40
* ---- -------- -------- ------------------------------------------------
41
* 1.17 08-22-94 Schuler Fixed one function not returning a value
44
* 05-19-95 Schuler Added rcs Log directive for automatic insertion of
45
* modification comments.
47
* Revision $Log: cdconfig.c,v $
48
* Revision Revision 6.1 1998/12/04 23:35:07 kans
49
* Revision KludgeCdromlibGetAppParam supplies ncbi config values for psrventr
51
* Revision Revision 6.0 1997/08/25 18:12:45 madden
52
* Revision Revision changed to 6.0
54
* Revision Revision 5.1 1997/06/26 21:55:25 vakatov
55
* Revision [PC] DLL'd "ncbicdr.lib", "ncbiacc.lib", "ncbinacc.lib" and "ncbicacc.lib"
57
* Revision Revision 5.0 1996/05/28 13:55:34 ostell
58
* Revision Set to revision 5.0
60
* Revision 4.1 1995/08/24 20:44:01 epstein
61
* add more stuff for genomes
63
* Revision 4.0 1995/07/26 13:50:32 ostell
64
* force revision to 4.0
66
* Revision 1.22 1995/05/16 14:36:20 schuler
67
* Automatic comment insertion enabled
70
* ==========================================================================
73
#define REVISION_STR "$Revision: 6.1 $"
78
/*****************************************************************************
80
* Kludge to eliminate need for old entries in ncbi config file
82
*****************************************************************************/
84
static CharPtr kludgecdromstrings [] = {
85
"ENTR_LINK.CHANNELS", "LINKS_FROM_NET",
86
"ENTR_REF.CHANNELS", "REFERENCE_FROM_NET",
87
"ENTR_SEQ.CHANNELS", "SEQUENCE_FROM_NET",
88
"ENTREZ_NET.FORMAL_NAME", "",
89
"ENTREZ_NET.RESOURCE_NAME", "Entrez",
90
"ENTREZ_NET.RESOURCE_TYPE", "Entrez",
91
"ENTREZ_NET.SERVICE_NAME", "Entrez",
92
"ENTREZ_NET.TYPE", "NET",
93
"LINKS_FROM_NET.ENTR_REF__ENTR_REF", "1",
94
"LINKS_FROM_NET.ENTR_REF__ENTR_SEQ", "1",
95
"LINKS_FROM_NET.ENTR_SEQ__ENTR_REF", "1",
96
"LINKS_FROM_NET.ENTR_SEQ__ENTR_SEQ", "1",
97
"LINKS_FROM_NET.INFO", "1",
98
"LINKS_FROM_NET.MEDIA", "ENTREZ_NET",
99
"NCBI.MEDIA", "ENTREZ_NET",
100
"REFERENCE_FROM_NET.BOOLEANS", "1",
101
"REFERENCE_FROM_NET.DOCSUMS", "1",
102
"REFERENCE_FROM_NET.MEDIA", "ENTREZ_NET",
103
"REFERENCE_FROM_NET.RECORDS", "1",
104
"REFERENCE_FROM_NET.TERMS", "1",
105
"SEQUENCE_FROM_NET.BOOLEANS", "1",
106
"SEQUENCE_FROM_NET.DOCSUMS", "1",
107
"SEQUENCE_FROM_NET.MEDIA", "ENTREZ_NET",
108
"SEQUENCE_FROM_NET.RECORDS", "1",
109
"SEQUENCE_FROM_NET.TERMS", "1",
115
void CDECL Nlm_WriteLog VPROTO((char *format, ...));
118
static Int2 KludgeCdromlibGetAppParam (CharPtr file, CharPtr section, CharPtr type,
119
CharPtr dflt, CharPtr buf, Int2 buflen)
125
if (buf == NULL || buflen < 1) return 0;
128
StringNCpy_0 (buf, dflt, buflen);
130
if (StringICmp (file, "NCBI") != 0) return 0;
131
if (StringLen (section) > 127 || StringLen (type) > 127) return 0;
132
StringCpy (str, section);
133
StringCat (str, ".");
134
StringCat (str, type);
135
for (i = 0; kludgecdromstrings [i] != NULL; i += 2) {
136
if (StringICmp (kludgecdromstrings [i], str) == 0) {
137
StringNCpy_0 (buf, kludgecdromstrings [i + 1], buflen);
138
return StringLen (buf);
142
GetAppParam (file, section, type, dflt, buf, buflen);
143
Nlm_WriteLog (" \"%s.%s\", \"%s\",\n", section, type, buf);
145
return StringLen (buf);
148
/* =========================================================================
153
static MediaPtr CurMedia = NULL;
154
static MediaPtr LRUMediaList = NULL;
156
static MediaPtr MediaList = NULL;
157
static DrasticActionsPtr DrasticList = NULL;
158
static DataSourceDbPtr DataSourceDbList = NULL;
159
static DataSourceDbPtr CurDataSourceDb = NULL;
160
static int numcfginits = 0;
161
static EntrezInfoPtr MergedEntrezInfo = NULL;
162
static Boolean SoleMedia = FALSE;
164
static char * sCdConfError[] =
167
"No data source %Fs for section %Fs field %Fs"
169
"No data source %s for section %s field %s"
176
/*****************************************************************************
178
* Private Function Prototypes
180
*****************************************************************************/
182
static void FreeConfig PROTO((void));
183
static Boolean ChangeMedia PROTO((MediaPtr newmedia));
184
static Boolean IsDrasticAction PROTO((MediaPtr fromMedia,
186
static DataSourceDbPtr LoadDataSourceInfo PROTO((CharPtr section,
187
CharPtr field1, CharPtr field2));
188
static void MarkMRU PROTO((MediaPtr m));
189
static MediaPtr FindLRU PROTO((void));
190
static void MarkLRUineligible PROTO((MediaPtr media));
191
static void UnMarkLRUineligible PROTO((void));
192
static void InitLRUeligibility PROTO((Int2 mask));
193
static Boolean AllCdDrivesAreFull PROTO((void));
194
static Boolean IsLiveMedia PROTO((MediaPtr media));
198
/***************************************************************************
203
***************************************************************************/
205
NLM_EXTERN void ConfigInit(void)
210
/***************************************************************************
215
***************************************************************************/
217
NLM_EXTERN void ConfigFini(void)
222
if (numcfginits == 0)
226
/***************************************************************************
228
* LoadDataSourceInfo()
230
* Called to load from the config file the information for a given
231
* section/field1/field2 combination, e.g., "ENTR_LINK"/"ENTR_REF"/"ENTR_SEQ",
232
* or "ENTR_REF"/"DOCSUMS"/NULL.
234
* The resulting data is stored as a linked list, sorted by decreasing
235
* priority. These "DataSourceDb" lists in turn are stored, in no particular
236
* order, in a master list, headed by DataSourceDbList.
238
***************************************************************************/
240
static DataSourceDbPtr LoadDataSourceInfo (CharPtr section, CharPtr field1,
243
DataSourceDbPtr dsdp;
252
Boolean no_drastic_action;
254
DataSourcePtr trailptr;
261
/* search the existing "data source database" to see if this entry is */
263
for (dsdp = DataSourceDbList; dsdp != NULL; dsdp = dsdp->next)
265
if ((section != NULL || dsdp->key.section != NULL) &&
266
StringCmp(section, dsdp->key.section) != 0)
268
if ((field1 != NULL || dsdp->key.field1 != NULL) &&
269
StringCmp(field1, dsdp->key.field1) != 0)
271
if ((field2 != NULL || dsdp->key.field2 != NULL) &&
272
StringCmp(field2, dsdp->key.field2) != 0)
279
if (KludgeCdromlibGetAppParam("NCBI", section, "CHANNELS", "", channels,
280
sizeof(channels)) == 0)
282
return NULL; /* can't find CHANNELS keyword */
285
/* insert at head of DB list (for simplicity) */
286
dsdp = (DataSourceDbPtr) MemNew(sizeof(DataSourceDb));
287
dsdp->next = DataSourceDbList;
288
DataSourceDbList = dsdp;
290
dsdp->key.section = section == NULL ? NULL : StringSave(section);
291
dsdp->key.field1 = field1 == NULL ? NULL : StringSave(field1);
293
StrCpy(field, field1);
296
dsdp->key.field2 = NULL;
298
else { /* contraction of two fields */
299
dsdp->key.field2 = StringSave(field2);
301
StrCat(field, field2);
310
/* Note that we don't use strtok() because it's not re-entrant */
311
while ((d1 = StringPBrk(d2, ",\n\r")) != NULL && !done)
313
if (*d1 == '\n' || *d1 == '\r' || *d1 == '\0')
318
d2 += StringSpn(d2, " \t"); /* remove leading spaces and tabs from next word */
319
KludgeCdromlibGetAppParam("NCBI", word, field, field2 == NULL ? "1" : "0", buf, sizeof(buf));
320
no_drastic_action = FALSE;
322
/* Fields with field2 != NULL represent an NxN matrix of values; therefore, */
323
/* we default the priorities to 0, to avoid having to declare all NxN values */
324
/* in the configuration file. */
329
channel = StringSave(word);
331
/* Parse the field which was just read, which contains a priority */
332
/* and may contain some other things as well. */
335
if ((d3 = StringPBrk(d4, ",\n\r")) != NULL)
340
StrCpy(priostr, word); /* workaround for Windows */
341
priority = atoi(priostr);
342
d4 += StringSpn(d4, " \t"); /* remove leading spaces and tabs from next word */
343
if (StrCmp(d4, "NO_DRASTIC_ACTION\n") == 0)
344
no_drastic_action = TRUE;
347
if (KludgeCdromlibGetAppParam("NCBI", channel, "MEDIA", "", buf, sizeof(buf)) == 0)
349
return NULL; /* media not specified */
351
media = PreInitMedia(buf);
353
/* override kludge for MEDIA; this enables a caller to make a */
354
/* particular CHANNEL active, without needing to know any of the */
355
/* names of the fields in that channel, except for "MEDIA" */
356
if (StrCmp(field, "MEDIA") == 0)
358
/* the really kludgy part of the kludge is to give preference to */
359
/* network-based media; there's no good reason for this ... it */
360
/* just makes it possible to run the multi-CD/network combo */
361
/* version without ejecting CD-ROMs upon startup */
362
if (media->media_type == MEDIUM_NETWORK)
368
dsp = (DataSourcePtr) MemNew(sizeof(DataSource));
370
/* order list by decreasing priorities */
372
if (dsdp->list == NULL)
375
if (dsdp->list->next == NULL) /* one-element list */
377
if (dsdp->list->priority < priority)
379
dsp->next = dsdp->list;
382
else { /* inserted element had lower priority; place at end of list */
383
dsdp->list->next = dsp;
387
/* The "trailptr" points one element behind the element */
388
/* which is being examined, so that the new element can be */
389
/* inserted BEFORE the element with lower priority */
390
for (trailptr = dsdp->list; trailptr->next != NULL;
391
trailptr = trailptr->next)
393
if (trailptr->next->priority < priority)
395
dsp->next = trailptr->next;
396
trailptr->next = dsp;
400
if (trailptr->next == NULL) /* lowest priority in list */
401
{ /* insert at end */
402
trailptr->next = dsp;
408
dsp->channel = channel;
409
dsp->priority = priority;
410
dsp->no_drastic_action = no_drastic_action;
418
/***************************************************************************
422
* For backwards-compatability with "old-style" configuration files,
423
* we need the ability to specify a "sole media". A sole-media, by implication,
424
* is the "valid" medium for all requested data sources, and should never
425
* be ejected (if it is a CD-ROM, which is likely).
427
***************************************************************************/
429
NLM_EXTERN void SetSoleMedia(void)
435
/***************************************************************************
439
* Find a "data source" for the specified section/field1/field2 combination,
440
* e.g., "ENTR_LINK"/"ENTR_REF"/"ENTR_SEQ", or "ENTR_REF"/"DOCSUMS"/NULL.
442
* Returns TRUE if we are able to satisfy the request.
444
***************************************************************************/
446
NLM_EXTERN Boolean SelectDataSource (CharPtr section, CharPtr field1, CharPtr field2)
448
DataSourceDbPtr dsdp;
451
#ifdef _NEW_CdEntrez_
453
return TRUE; /***** KLUDGE *****/
456
/* for backwards compatability with "old-style" config files */
458
{ /* use a single medium, rather than traversing a list */
459
CurDataSourceDb = NULL;
460
if (CurMedia == NULL)
461
{ /* no media yet initialized; so initialize it */
462
if (MediaList != NULL)
463
{ /* MediaList points to single media entry */
464
return ChangeMedia(MediaList);
468
else { /* already set-up */
473
if ((dsdp = LoadDataSourceInfo(section, field1, field2)) == NULL)
475
ErrPost (CTX_NCBICD, ERR_CD_NO_DATASRC, sCdConfError[0], "", section,
477
CurDataSourceDb = NULL;
481
CurDataSourceDb = dsdp;
483
if (dsdp->list == NULL)
485
ErrPost (CTX_NCBICD, ERR_CD_NO_DATASRC, sCdConfError[0], "list ",
490
/* Mark all entries as being "not yet searched", except for "invalid" */
492
for (dsp = dsdp->list; dsp != NULL; dsp = dsp->next)
494
dsp->already_searched = dsp->media == NULL || dsp->media->invalid;
497
return SelectNextDataSource();
500
/***************************************************************************
502
* SelectDataSourceByType()
503
* * A short-hand mechanism for selecting the appropriate SelectDataSource()
506
****************************************************************************/
508
NLM_EXTERN Boolean SelectDataSourceByType (DocType type, CharPtr field1, CharPtr field2)
512
#ifdef _NEW_CdEntrez_
514
return TRUE; /***** KLUDGE *****/
523
section = ENTR_SEQ_CHAN;
526
section = ENTR_REF_CHAN;
532
return SelectDataSource(section, field1, field2);
535
/***************************************************************************
537
* SelectDataSourceByType()
539
* A short-hand mechanism for specifying the SelectDataSource() arguments
540
* for the "ENTR_LINK" section. Note that entries in the "ENTR_LINK" section
541
* are specified by the "from-type" name, followed by two underscores, followed
542
* by the "to-type" name.
544
****************************************************************************/
546
NLM_EXTERN Boolean SelectDataLinksByTypes (DocType type, DocType link_to_type)
551
#ifdef _NEW_CdEntrez_
553
return TRUE; /***** KLUDGE *****/
562
field1 = ENTR_SEQ_CHAN;
565
field1 = ENTR_REF_CHAN;
571
switch (link_to_type) {
577
field2 = ENTR_SEQ_CHAN;
580
field2 = ENTR_REF_CHAN;
586
return SelectDataSource(ENTR_LINKS_CHAN, field1, field2);
589
/***************************************************************************
591
* SelectNextDataSource()
593
* Called subsequent to SelectDataSource(), to find the next {or first,
594
* when called by SelectDataSource()} available data source for the
595
* previously selected section/field1/field2 combination.
597
****************************************************************************/
599
NLM_EXTERN Boolean SelectNextDataSource (void)
601
DataSourceDbPtr dsdp = CurDataSourceDb;
603
DataSourcePtr best_entry;
604
DataSourcePtr best_on_live_media;
606
#ifdef _NEW_CdEntrez_
608
return FALSE; /***** KLUDGE *****/
612
{ /* no current data source "database" */
616
/* loop forever (until return) */
619
best_on_live_media = NULL;
621
/* Try to find an entry associated with the current media, provided */
622
/* the current media is a live media (select the one which appears */
623
/* first in the list, and thus has the highest priority */
624
for (dsp = dsdp->list; dsp != NULL; dsp = dsp->next)
626
if (dsp->priority > 0 && !dsp->already_searched &&
627
dsp->media == CurMedia && IsLiveMedia(dsp->media))
629
best_on_live_media = dsp;
634
/* Try to find an entry associated with a live media (select */
635
/* the one which appears first in the list, and thus has the highest */
637
for (dsp = dsdp->list; best_on_live_media == NULL && dsp != NULL;
640
if (dsp->priority > 0 && !dsp->already_searched &&
641
IsLiveMedia(dsp->media))
643
best_on_live_media = dsp;
648
/* Search for an entry with a higher priority than that associated */
649
/* with best_on_live_media, for which drastic-actions are not */
650
/* disallowed (unless switching to that media is not a "drastic */
652
best_entry = best_on_live_media;
654
for (dsp = dsdp->list; dsp != NULL && dsp->priority > 0; dsp = dsp->next)
656
if (dsp->already_searched)
659
if (best_on_live_media != NULL &&
660
dsp->priority <= best_on_live_media->priority)
662
break; /* nothing found better than the "live" media */
665
if (!(dsp->no_drastic_action) || best_on_live_media == NULL ||
666
!IsDrasticAction(CurMedia, dsp->media))
667
{ /* found a better medium */
673
if (best_entry == NULL)
678
for (dsp = dsdp->list; dsp != NULL; dsp = dsp->next)
679
{ /* mark all entries associated with this media as "already searched" */
680
if (dsp->media == best_entry->media)
681
dsp->already_searched = TRUE;
684
if (best_entry->media != CurMedia)
686
if (ChangeMedia (best_entry->media))
689
else { /* the current Media was fine */
695
/***************************************************************************
699
* Free and reset all configuration data. This should be used sparingly
700
* since it resets all configuration information gathered to date.
702
****************************************************************************/
704
static void FreeConfig(void)
707
DataSourceDbPtr dsdp, nextdsdp;
708
DataSourcePtr dsp, nextdsp;
709
DrasticActionsPtr dap, nextdap;
713
/* Free all the dynamically allocated lists of config data */
715
for (mp = MediaList; mp != NULL; mp = nextmp)
717
MemFree(mp->media_alias);
718
MemFree(mp->formal_name);
721
{ /* CdFini()/NetFini() will take care of this for us for CurMedia */
722
EntrezInfoFree(mp->entrez_info);
725
switch(mp->media_type) {
728
cmip = (CdMediaInfoPtr) mp->media_info;
732
if (cmip->device_name != NULL)
733
MemFree (cmip->device_name);
734
if (cmip->mount_point != NULL)
735
MemFree (cmip->mount_point);
736
if (cmip->mount_cmd != NULL)
737
MemFree (cmip->mount_cmd);
739
{ /* CdFini() will take care of this for us for CurMedia */
740
for (i = 0; i < NDIR; i++)
742
if (cmip->sPath[i] != NULL)
743
MemFree(cmip->sPath[i]);
746
/* to avoid future references to a freed data structure */
754
MemFree(mp->media_info);
763
for (dsdp = DataSourceDbList; dsdp != NULL; dsdp = nextdsdp)
765
MemFree(dsdp->key.section);
766
MemFree(dsdp->key.field1);
767
MemFree(dsdp->key.field2);
768
/* Each DataSourceDbList entry references one or more DataSource */
770
for (dsp = dsdp->list; dsp != NULL; dsp = nextdsp)
772
MemFree(dsp->channel);
776
nextdsdp = dsdp->next;
780
DataSourceDbList = NULL;
782
for (dap = DrasticList; dap != NULL; dap = nextdap)
790
if (MergedEntrezInfo != NULL)
791
EntrezInfoFree (MergedEntrezInfo);
792
MergedEntrezInfo = NULL;
796
/***************************************************************************
800
* Obtain the current media. Provided to allow the CurMedia variable to be
801
* "hidden" within this file.
803
****************************************************************************/
805
NLM_EXTERN MediaPtr GetCurMedia (void)
810
/***************************************************************************
814
* Obtain the current media type, or MEDIUM_UNKNOWN, if the media type has
817
****************************************************************************/
819
NLM_EXTERN Int2 CurMediaType (void)
822
#ifdef _NEW_CdEntrez_
824
return MEDIUM_CD; /***** KLUDGE *****/
828
if (CurMedia == NULL)
829
return MEDIUM_UNKNOWN;
831
return CurMedia->media_type;
834
/***************************************************************************
838
* Set the current media. Provided to allow the CurMedia variable to be
839
* "hidden" within this file. To be used cautiously.
841
****************************************************************************/
843
NLM_EXTERN MediaPtr SetCurMedia (MediaPtr NewMedia)
849
/***************************************************************************
853
* Used to see whether a switch between two media is considered to be a
854
* "drastic action", i.e., something to be avoided. When it becomes known
855
* whether a given switch is considered to be "drastic", that information
856
* is stored in a linked list. Requests which cannot be satisfied from that
857
* list are searched in the configuration file, and the results are
858
* subsequently stored in that list.
860
****************************************************************************/
862
static Boolean IsDrasticAction(MediaPtr fromMedia, MediaPtr toMedia)
868
/* First try to obtain "drastic" information from a cached list */
869
for (d = DrasticList; d != NULL; d = d->next)
871
if (d->from_media == fromMedia && d->to_media == toMedia)
872
return d->is_drastic;
875
/* If unable to find it on the cached list, search the config file */
876
/* and then add the information to the cached list */
878
StrCpy(drastic_to, "DRASTIC_TO_");
879
StrCat(drastic_to, toMedia->media_alias);
881
d = (DrasticActionsPtr) MemNew(sizeof(DrasticActions));
882
d->from_media = fromMedia;
883
d->to_media = toMedia;
884
d->is_drastic = KludgeCdromlibGetAppParam("NCBI", fromMedia->media_alias, drastic_to,
885
"", buf, sizeof(buf)) > 0;
886
d->next = DrasticList;
888
return d->is_drastic;
891
/***************************************************************************
895
* Make the specified media the "active" media. This requires "swapping out"
896
* the old media, if one is active, and may require, e.g., ejecting a CD-ROM
897
* to make room for a new one.
899
****************************************************************************/
901
static Boolean ChangeMedia(MediaPtr newMedia)
903
if (newMedia == NULL)
906
if (newMedia == CurMedia)
909
if (CurMedia != NULL)
911
CurMedia->is_live = FALSE;
914
if (newMedia->media_type == MEDIUM_CD)
916
MediaPtr toBeEjected;
921
InitLRUeligibility(MEDIUM_CD);
922
/* the media which we want to be inserted is ineligible for ejection */
923
MarkLRUineligible(newMedia);
925
while (! CdIsInserted(newMedia))
929
if (AllCdDrivesAreFull())
931
if ((toBeEjected = FindLRU()) != NULL)
932
{ /* it's the user's problem if there are none to be ejected */
933
MarkLRUineligible(toBeEjected);
934
if (toBeEjected->media_type == MEDIUM_CD &&
935
CdIsInserted(toBeEjected) &&
936
(cdm = (CdMediaInfoPtr) toBeEjected->media_info) !=
939
if (toBeEjected->entrez_info != NULL)
941
EjectCd(toBeEjected->entrez_info->volume_label,
942
cdm->device_name, cdm->raw_device_name,
943
cdm->mount_point, cdm->mount_cmd);
949
StrCpy (msg, "Please insert <");
950
StrCat (msg, newMedia->formal_name);
951
StrCat (msg, ">; select OK when ready");
952
if (Message(MSG_OKC, msg) == ANS_CANCEL)
957
if ((cdm = (CdMediaInfoPtr) newMedia->media_info) != NULL &&
958
newMedia->entrez_info != NULL)
960
MountCd(newMedia->entrez_info->volume_label, cdm->device_name,
961
cdm->mount_point, cdm->mount_cmd);
966
if (CurMedia != NULL && CurMedia->swapOutMedia != NULL)
968
CurMedia->swapOutMedia(CurMedia);
970
if (newMedia->swapInMedia != NULL)
972
newMedia->swapInMedia(newMedia);
977
CurMedia->is_live = TRUE;
981
/***************************************************************************
985
* Perform the pre-initialization of a media. This is the initialization which
986
* which may be performed when, e.g., a Network Service is not yet available,
987
* or a CD-ROM is not yet inserted into a CD-ROM drive. Subsequently
988
* initialization may be performed at a later time when the media becomes
991
****************************************************************************/
993
NLM_EXTERN MediaPtr PreInitMedia (CharPtr mediaName)
998
for (m = MediaList; m != NULL; m = m->next)
1000
if (StrCmp(mediaName, m->media_alias) == 0)
1001
return m; /* already have it */
1004
if (KludgeCdromlibGetAppParam("NCBI", mediaName, "TYPE", "", buf, sizeof(buf)) == 0 && !SoleMedia)
1007
m = (MediaPtr) MemNew(sizeof(Media));
1009
m->media_type = MEDIUM_UNKNOWN;
1011
m->media_type = MEDIUM_DISK;
1013
if (StrCmp(buf, "CD") == 0)
1014
m->media_type = MEDIUM_CD;
1015
if (StrCmp(buf, "NET") == 0)
1016
m->media_type = MEDIUM_NETWORK;
1017
if (StrCmp(buf, "HARDDISK") == 0)
1018
m->media_type = MEDIUM_DISK;
1020
if (KludgeCdromlibGetAppParam("NCBI", mediaName, "FORMAL_NAME", "", buf, sizeof(buf)) != 0)
1022
m->formal_name = StringSave(buf);
1025
m->formal_name = StringSave(mediaName);
1028
m->inited_partial = FALSE;
1029
m->inited_total = FALSE;
1033
m->media_info = NULL;
1034
m->swapOutMedia = NULL;
1035
m->swapInMedia = NULL;
1036
m->finiMedia = NULL;
1037
m->media_alias = StringSave(mediaName);
1038
m->next = MediaList;
1039
m->LRUineligible = FALSE;
1040
if (LRUMediaList == NULL)
1041
{ /* now a single element in the list */
1045
else { /* insert into double-linked circular list */
1046
m->prev_lru = LRUMediaList->prev_lru;
1047
m->next_lru = LRUMediaList;
1048
LRUMediaList->prev_lru->next_lru = m;
1049
LRUMediaList->prev_lru = m;
1057
/***************************************************************************
1061
* Test to see whether the specified CD-ROM is currently inserted into a
1064
****************************************************************************/
1066
NLM_EXTERN Boolean CdIsInserted(MediaPtr media)
1068
Boolean retval = FALSE;
1069
#ifdef _OLD_CdEntrez_
1073
EntrezInfoPtr pre_init_vi;
1078
#ifdef _NEW_CdEntrez_
1080
retval = TRUE; /***** KLUDGE *****/
1083
#ifdef _OLD_CdEntrez_
1088
if ( (cdm = (CdMediaInfoPtr) media->media_info) == NULL)
1090
if ( (pre_init_vi = media->entrez_info) == NULL)
1093
ErrGetOpts(&erract, NULL);
1094
ErrSetOpts(ERR_IGNORE, 0);
1096
if ((aip = EntrezInfoOpen(cdm->sPath[DIR_ROOT])) != NULL)
1098
vi = EntrezInfoAsnRead(aip, NULL);
1102
if (StrCmp(vi->volume_label, pre_init_vi->volume_label) ==
1104
vi->version == pre_init_vi->version &&
1105
vi->issue == pre_init_vi->issue &&
1106
vi->format == pre_init_vi->format)
1112
ErrFetch(&err); /* discard error */
1115
ErrSetOpts(erract, 0); /* restore previous error status */
1121
/***************************************************************************
1125
* Perform an "optomistic merge" of all the available EntrezInfo data
1126
* from the different known media. If there is only a single known medium,
1127
* then this degrades to returning the EntrezInfo for that medium. Otherwise,
1128
* the "type" entries with the maximum amount of sub-entries are selected.
1130
****************************************************************************/
1132
NLM_EXTERN EntrezInfoPtr EntrezInfoMerge(void)
1140
EntrezInfoPtr InfoWithMaxTypes;
1141
EntrezTypeDataPtr besttype;
1143
Int2 mediaCount = 0;
1145
/* first, find out how many types there are, and save a pointer to an */
1146
/* entry which has that many types */
1147
for (mp = MediaList; mp != NULL; mp = mp->next)
1149
if ( (cip = mp->entrez_info) == NULL)
1152
if (cip->type_count <= MaxTypes)
1154
MaxTypes = cip->type_count;
1155
InfoWithMaxTypes = cip;
1161
if (MergedEntrezInfo != NULL)
1162
EntrezInfoFree(MergedEntrezInfo);
1164
new = (EntrezInfoPtr) MemNew(sizeof(EntrezInfo));
1165
MergedEntrezInfo = new;
1166
new->volume_label = StringSave(InfoWithMaxTypes->volume_label);
1167
new->version = InfoWithMaxTypes->version;
1168
new->issue = InfoWithMaxTypes->issue;
1169
new->format = InfoWithMaxTypes->format;
1170
new->descr = StringSave(InfoWithMaxTypes->descr);
1172
/* there is no way to merge compression information if there is more than */
1174
if (mediaCount <= 1 && ! InfoWithMaxTypes->no_compression) {
1175
new->no_compression = InfoWithMaxTypes->no_compression;
1176
new->huff_count = InfoWithMaxTypes->huff_count;
1177
new->huff_left = MemDup (InfoWithMaxTypes->huff_left,
1178
sizeof(new->huff_left[0]) * new->huff_count);
1179
new->huff_right = MemDup (InfoWithMaxTypes->huff_right,
1180
sizeof(new->huff_right[0]) * new->huff_count);
1182
new->no_compression = TRUE;
1183
new->huff_count = 0;
1184
new->huff_left = NULL;
1185
new->huff_right = NULL;
1188
new->type_count = MaxTypes;
1189
new->type_bucket_size = InfoWithMaxTypes->type_bucket_size;
1190
new->field_count = InfoWithMaxTypes->field_count;
1191
new->field_bucket_size = InfoWithMaxTypes->field_bucket_size;
1193
new->type_names = (CharPtr PNTR) MemNew(sizeof(CharPtr) * MaxTypes);
1194
new->field_names = (CharPtr PNTR) MemNew(sizeof(CharPtr) *
1196
new->types = (EntrezTypeDataPtr) MemNew(sizeof(EntrezTypeData) * MaxTypes);
1197
if (InfoWithMaxTypes->type_info != NULL)
1199
new->type_info = (EntrezTypeInfo PNTR) MemNew(sizeof(EntrezTypeInfo) * MaxTypes);
1201
if (InfoWithMaxTypes->field_info != NULL)
1203
new->field_info = (EntrezFieldInfo PNTR)
1204
MemNew(sizeof(EntrezFieldInfo) *
1205
InfoWithMaxTypes->field_count);
1208
for (i = 0; i < InfoWithMaxTypes->field_count; i++)
1210
new->field_names[i] = StringSave(InfoWithMaxTypes->field_names[i]);
1211
if (new->field_info != NULL)
1213
new->field_info[i] = InfoWithMaxTypes->field_info[i];
1214
new->field_info[i].name = StringSave(InfoWithMaxTypes->field_info[i].name);
1215
new->field_info[i].descr = StringSave(InfoWithMaxTypes->field_info[i].descr);
1219
for (i = 0; i < MaxTypes; i++)
1221
new->type_names[i] = StringSave(InfoWithMaxTypes->type_names[i]);
1222
if (new->type_info != NULL)
1224
new->type_info[i].id = InfoWithMaxTypes->type_info[i].id;
1225
StrCpy(new->type_info[i].tag,InfoWithMaxTypes->type_info[i].tag);
1226
new->type_info[i].name = StringSave(InfoWithMaxTypes->type_info[i].name);
1227
new->type_info[i].descr = StringSave(InfoWithMaxTypes->type_info[i].descr);
1228
new->type_info[i].asntype = StringSave(InfoWithMaxTypes->type_info[i].asntype);
1233
/* for each "type", traverse the media list and find the "best" one */
1234
for (mp = MediaList; mp != NULL; mp = mp->next)
1236
if ( (cip = mp->entrez_info) == NULL)
1238
if (cip->type_count < i)
1240
if (cip->types[i].num < count)
1242
/* the "best" type is the one with the most entries */
1243
besttype = &(cip->types[i]);
1244
count = besttype->num;
1246
new->types[i].num = besttype->num;
1247
new->types[i].num_uids = besttype->num_uids;
1248
new->types[i].minuid = besttype->minuid;
1249
new->types[i].maxuid = besttype->maxuid;
1250
new->types[i].num_bucket = besttype->num_bucket;
1251
new->types[i].fields = (EntrezFieldDataPtr) MemNew(
1252
sizeof(EntrezFieldData) *
1253
InfoWithMaxTypes->field_count);
1254
for (f = 0; f < InfoWithMaxTypes->field_count; f++)
1256
new->types[i].fields[f].num_terms =
1257
besttype->fields[f].num_terms;
1258
new->types[i].fields[f].num_bucket =
1259
besttype->fields[f].num_bucket;
1267
/***************************************************************************
1271
* Find the "least-recently-used" entry in a doubly-linked-queue of media,
1272
* with the additional constraint that the selected medium may not be marked
1275
****************************************************************************/
1277
static MediaPtr FindLRU(void)
1281
if (LRUMediaList == NULL)
1284
media = LRUMediaList;
1286
/* traverse media list, beginning with Least-Recently-Used, searching for an */
1287
/* eligible candidate */
1289
media = media->prev_lru;
1290
if (! media->LRUineligible)
1292
} while (media != NULL && media != LRUMediaList);
1297
/***************************************************************************
1299
* MarkLRUineligible()
1301
* Mark a medium as "ineligible" to be considered in a search for a
1302
* least-recently-used medium.
1304
****************************************************************************/
1306
static void MarkLRUineligible(MediaPtr media)
1310
media->LRUineligible = TRUE;
1314
/***************************************************************************
1316
* InitLRUeligibility()
1318
* Mark all media as not-"ineligible", i.e., eligible, to be considered
1319
* in a search for the least-recently-used medium ... provided that they
1320
* are of the specified media-type. All other media are ineligible.
1322
****************************************************************************/
1324
static void InitLRUeligibility(Int2 mask)
1326
MediaPtr m = LRUMediaList;
1332
if (m->media_type & mask)
1333
m->LRUineligible = FALSE;
1335
m->LRUineligible = TRUE;
1337
} while (m != LRUMediaList);
1340
/***************************************************************************
1344
* Mark this medium as the "most-recently-used" by moving it to the
1345
* head (or tail, depending upon how you look at it) of a doubly-linked
1348
****************************************************************************/
1350
static void MarkMRU(MediaPtr m)
1351
{ /* mark this entry as most recently used by moving to head of Queue */
1353
if (m == NULL || LRUMediaList == NULL)
1356
/* already Most-Recently-Used; and besides, the algorithm that follows */
1357
/* will produce spaghetti if m already points to the head of the queue */
1358
if (m == LRUMediaList)
1361
/* delete entry from neighbors' links */
1362
m->prev_lru->next_lru = m->next_lru;
1363
m->next_lru->prev_lru = m->prev_lru;
1365
/* insert at beginning of list */
1366
m->prev_lru = LRUMediaList->prev_lru;
1367
m->next_lru = LRUMediaList;
1368
LRUMediaList->prev_lru->next_lru = m;
1369
LRUMediaList->prev_lru = m;
1373
/***************************************************************************
1375
* AllCdDrivesAreFull()
1377
* Returns TRUE if all availabe CD-ROM drives are currently full. This
1378
* should be done by searching the known CD-ROM drives for a "vacancy",
1379
* but this is currently difficult to perform.
1381
****************************************************************************/
1383
static Boolean AllCdDrivesAreFull(void)
1384
{ /* for now, be pessimistic */
1388
/***************************************************************************
1392
* Indicates whether the specified media is "live". This means either,
1393
* e.g., a currently inserted CD-ROM, or a currently active network service,
1396
****************************************************************************/
1398
static Boolean IsLiveMedia (MediaPtr media)
1406
if (media->media_type == MEDIUM_DISK)
1407
return CdIsInserted(media);
1409
if (media->media_type == MEDIUM_CD)
1410
return CdIsInserted(media);
1412
if (media->media_type == MEDIUM_NETWORK)
1419
NLM_EXTERN Int2 ParseMedia(ConfCtlProc initfunc, Int2 media_mask)
1426
Int2 numProcessed = 0;
1428
KludgeCdromlibGetAppParam ("ncbi", "NCBI", "MEDIA", "", media, sizeof media);
1430
/* This is a work-around to provide backwards compatibility for old */
1431
/* config files which do not specify MEDIA */
1432
if (media[0] == '\0')
1434
StrCpy(media, "NCBI");
1442
/* parse "MEDIA", looking for all data sources; note that we don't use */
1443
/* strtok(), because it's not re-entrant */
1444
while ((m1 = StringPBrk(m2, ",\n\r")) != NULL && !done)
1446
if (*m1 == '\n' || *m1 == '\r' || *m1 == '\0')
1451
m2 += StringSpn(m2, " \t"); /* remove leading spaces and tabs from next word */
1453
mp = PreInitMedia(word);
1454
if (mp->media_type & media_mask)
1456
if (initfunc != NULL)
1461
mp->invalid = FALSE;
1467
mp->invalid = FALSE;
1477
return numProcessed;