1 /*
2  *
3  *  Copyright (C) 1993-2017, OFFIS e.V.
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation were developed by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module:  dcmqrdb
15  *
16  *  Author:  Marco Eichelberg / Ralph Meyer
17  *
18  *  Purpose: class DcmQueryRetrieveConfig
19  *
20  */
21 
22 #ifndef DCMQRCNF_H
23 #define DCMQRCNF_H
24 
25 #include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
26 
27 #define INCLUDE_CSTDIO
28 #include "dcmtk/ofstd/ofstdinc.h"
29 #include "dcmtk/ofstd/ofcmdln.h"
30 #include "dcmtk/oflog/oflog.h"
31 #include "dcmtk/dcmqrdb/qrdefine.h"
32 
33 extern DCMTK_DCMQRDB_EXPORT OFLogger DCM_dcmqrdbLogger;
34 
35 #define DCMQRDB_TRACE(msg) OFLOG_TRACE(DCM_dcmqrdbLogger, msg)
36 #define DCMQRDB_DEBUG(msg) OFLOG_DEBUG(DCM_dcmqrdbLogger, msg)
37 #define DCMQRDB_INFO(msg)  OFLOG_INFO(DCM_dcmqrdbLogger, msg)
38 #define DCMQRDB_WARN(msg)  OFLOG_WARN(DCM_dcmqrdbLogger, msg)
39 #define DCMQRDB_ERROR(msg) OFLOG_ERROR(DCM_dcmqrdbLogger, msg)
40 #define DCMQRDB_FATAL(msg) OFLOG_FATAL(DCM_dcmqrdbLogger, msg)
41 
42 /** this class describes configuration settings regarding character set handling
43  */
44 struct DCMTK_DCMQRDB_EXPORT DcmQueryRetrieveCharacterSetOptions
45 {
46     /** Flags for controlling the application behavior regarding character set
47      *  conversion. Might be used for global and for per peer configuration.
48      */
49     enum Flags
50     {
51         /** Activate options for Specific Character Set.
52          *  If this flag is not set, all other flags and the given string for
53          *  Specific Character Set will be ignored, e.g. using the global
54          *  settings instead of peer specific ones.
55          */
56         Configured = 0x01,
57 
58         /** Always respond using the given character set, ignoring the
59          *  character set of the request.
60          *  If this flag is not set, the response will be created to the
61          *  character set of the request (if possible).
62          */
63         Override   = 0x02,
64 
65         /** Fall back to another character set.
66          *  If this flag is set, the application will try to recover from a
67          *  conversion failure:
68          *    - If 'Override' is set, the application will try to convert
69          *      the response to the character set of the request if conversion
70          *      to the given character set failed.
71          *    - If 'Override' is not set, the application will try to convert
72          *      the response to the given character set if conversion to the
73          *      character set of the response failed.
74          *  If this flag is not set, the response will be left as-is, i.e.
75          *  like it is stored in the index file, if conversion to another
76          *  character set failed.
77          *  @note The fall back conversion might also fail, in which case
78          *    the response will still be left as-is, even if a fall back
79          *    option was given.
80          */
81         Fallback   = 0x04
82     };
83 
84     /** Constructor, will construct an object that is marked as
85      *  "not configured".
86      */
87     DcmQueryRetrieveCharacterSetOptions();
88 
89     /** extract arguments from the config file.
90      *  @param mnemonic the name of the current option
91      *  @param valueptr the argument(s)
92      *  @return OFTrue if the given name value pair referred to a character
93      *    set option and was 'consumed', OFFalse if it should be handled
94      *    elsewhere.
95      */
96     OFBool parseOptions(const char* mnemonic, char* valueptr);
97 
98     /// the given character set
99     OFString characterSet;
100 
101     /** determine semantics of the character set value
102      *  @see DcmQueryRetrieveCharacterSet::Flags
103      */
104     unsigned flags;
105 
106     /** special character set conversion flags.
107      *  @see OFCharacterEncoding::ConversionFlags
108      */
109     unsigned conversionFlags;
110 };
111 
112 /** this class describes configuration settings for the quota of a storage area
113  */
114 struct DCMTK_DCMQRDB_EXPORT DcmQueryRetrieveConfigQuota
115 {
116     /// maximum number of studies
117     int  maxStudies;
118     /// maximum number of bytes per study
119     long maxBytesPerStudy;
120 };
121 
122 /** this class describes configuration settings for a remote SCP peer
123  */
124 struct DCMTK_DCMQRDB_EXPORT DcmQueryRetrieveConfigPeer
125 {
126     /// remote peer AE title
127     const char *ApplicationTitle;
128 
129     /// remote peer host name
130     const char *HostName;
131 
132     /// remote peer port number
133     int PortNumber;
134 };
135 
136 /** this class describes configuration settings for a single storage area
137  */
138 struct DCMTK_DCMQRDB_EXPORT DcmQueryRetrieveConfigAEEntry
139 {
140     /// application entity title
141     const char *ApplicationTitle;
142 
143     /// name of storage area
144     const char *StorageArea;
145 
146     /// access type (read-only, read/write)
147     const char *Access;
148 
149     /// quota setting for this storage area
150     DcmQueryRetrieveConfigQuota *StorageQuota;
151 
152     /// number of peer entries
153     int noOfPeers;
154 
155     /// array of peer entries describing remote SCP peers
156     DcmQueryRetrieveConfigPeer *Peers;
157 };
158 
159 /** this class describes configuration settings for a list of storage areas
160  */
161 struct DCMTK_DCMQRDB_EXPORT DcmQueryRetrieveConfigConfiguration
162 {
163     /// number of storage areas (aetitles)
164     int noOfAEEntries;
165 
166     /// array of entries for each storage area
167     DcmQueryRetrieveConfigAEEntry *AEEntries;
168 };
169 
170 /** this class describes configuration settings for one symbolic host or vendor
171  */
172 struct DCMTK_DCMQRDB_EXPORT DcmQueryRetrieveConfigHostEntry
173 {
174     /// symbolic name of host
175     const char *SymbolicName;
176 
177     /// number of peer entries
178     int noOfPeers;
179 
180     /// array of peer entries describing remote SCP peers
181     DcmQueryRetrieveConfigPeer *Peers;
182 };
183 
184 /** this class describes configuration settings for a list of symbolic hosts or vendors
185  */
186 struct DCMTK_DCMQRDB_EXPORT DcmQueryRetrieveConfigHostTable
187 {
188     /// number of entries
189     int noOfHostEntries;
190 
191     /// array of entries
192     DcmQueryRetrieveConfigHostEntry   *HostEntries;
193 };
194 
195 /** this class describes configuration settings for a Query/Retrieve SCP Service
196  */
197 class DCMTK_DCMQRDB_EXPORT DcmQueryRetrieveConfig
198 {
199 
200 public:
201 
DcmQueryRetrieveConfig()202   DcmQueryRetrieveConfig()
203   : UserName_()
204   , GroupName_()
205   , networkTCPPort_(0)
206   , maxPDUSize_(0)
207   , maxAssociations_(0)
208   , CNF_Config()
209   , CNF_HETable()
210   , CNF_VendorTable()
211   {
212   }
213 
214   ~DcmQueryRetrieveConfig();
215 
216   /*
217    *  read configuration file and initialize the
218    *  intern configuration structure
219    *  Input : configuration file name
220    *  Return : 1 - ok
221    *     0 - error
222    */
223   int init(const char *ConfigurationFile);
224 
225   /*
226    *  search for peer with AETitle
227    *  Input : AETitle
228    *  Ouput : Host Name, Port Number
229    *  Return : 1 - found in AETable
230    *     2 - found in HostTable
231    *     0 - not found
232    */
233   int peerForAETitle(const char *AETitle, const char **HostName, int *PortNumber) const;
234 
235   /*
236    *  check if given AETitles exist in same
237    *  Vendor Group
238    *  Input : two AETitles
239    *  Return : 1 - same group
240    *     0 - else
241    */
242   int checkForSameVendor(const char *AETitle1, const char *AETitle2) const;
243 
244   /*
245    *  get Storage Area for AETitle
246    *  Input : AETitle
247    *  Return : Storage Area
248    */
249   const char *getStorageArea(const char *AETitle) const;
250 
251   /*
252    *  get Number of Maximal Studies
253    *  Input : AETitle
254    *  Return : Number of Maximal Studies
255    */
256   int getMaxStudies(const char *AETitle) const;
257 
258   /*
259    *  get Number of maximal Bytes per Study
260    *  Input : AETitle
261    *  Return : Number of maximal Bytes per Study
262    */
263   long getMaxBytesPerStudy(const char *AETitle) const;
264 
265   /*
266    *  get Max Associations
267    *  Input :
268    *  Return : Max Associations
269    */
270   int getMaxAssociations() const;
271 
272   /*
273    *  get Network TCP Port
274    *  Input :
275    *  Return : Network TCP Port
276    */
277   int getNetworkTCPPort() const;
278 
279   /*
280    *  get Max PDU Size
281    *  Input :
282    *  Return : Max PDU Size
283    */
284   OFCmdUnsignedInt getMaxPDUSize() const;
285 
286   /*
287    *  check if there is an peer with calling AETitle
288    *  on HostName
289    *  Input : called AETitle, calling AETitle, Host Name
290    *  Return : 1 -- yes
291    *     0 -- no
292    */
293   int peerInAETitle(const char *calledAETitle, const char *callingAETitle, const char *HostName) const;
294 
295   /*
296    *  get Access mode
297    *  Input : AETitle
298    *  Return : Access mode
299    */
300   const char *getAccess(const char *AETitle) const;
301 
302   /*
303    *  check if given storage area is read/write
304    *  Input : AETitle
305    *  Return : true if storage area is writable
306    */
307   OFBool writableStorageArea(const char *aeTitle) const;
308 
309   // methods only used by TI
310 
311   /*
312    *  searches in the host table for all AE titles
313    *  known for peer hostName.  Creates an array of string pointers
314    *  containing the known AE titles.  The AE titles contained
315    *  in the array are privately owned by the config facility (you
316    *  may not free them).  You may free the array when no longer needed.
317    *
318    *  Input Parameter: peer host name
319    *  Output Parameter: malloc'ed array of private string pointers.
320    *  Returns : number of entries in the malloced array.
321    *      0 if no entries found.
322    */
323 
324   int aeTitlesForPeer(const char *hostName, const char *** aeTitleList) const;
325 
326   /*
327    *  Creates an array of string pointers
328    *  containing the known AE titles for CTN storage areas.
329    *  The AE titles contained in the array are privately owned
330    *  by the config facility (you may not free them).  You may
331    *  free the array when no longer needed.
332    *
333    *  Output Parameter: malloc'ed array of private string pointers.
334    *  Returns : number of entries in the malloced array.
335    *      0 if no entries exist.
336    */
337 
338   int ctnTitles(const char *** ctnTitleList) const;
339 
340   /*
341    *  Creates an array of string pointers
342    *  containing the kown Host Names for given Vendor Name.
343    *  The Host Names contained in the array are privately owned
344    *  by the config facility (you may not free them). You may
345    *  free the array when no longer needed.
346    *  Input : Vendor Name
347    *  Ouput : array of string pointers
348    *  Return : number of entries in array
349    *     0 if no entries exist
350    */
351   int HostNamesForVendor(const char *Vendor, const char ***HostNameArray) const;
352 
353   /*
354    *  searches in the host table for all AE titles
355    *  known for a symbolic name.  Creates an array of string pointers
356    *  containing the known AE titles.  The AE titles contained
357    *  in the array are privately owned by the config facility (you
358    *  may not free them).  You may free the array when no longer needed.
359    *
360    *  Input Parameter: symbolic name
361    *  Output Parameter: malloc'ed array of private string pointers.
362    *  Returns : number of entries in the malloced array.
363    *      0 if no entries found.
364    */
365   int aeTitlesForSymbolicName(const char *symbolicName, const char ***aeTitleList) const;
366 
367   /*
368    *  printf contents of configuration stucture
369    *  to stdout
370    */
371   void printConfig();
372 
373   /*
374    *  get User Name
375    *  Input :
376    *  Return : User Name
377    */
378   const char *getUserName() const;
379 
380   /*
381    *  get Group Name
382    *  Input :
383    *  Return : Group Name
384    */
385   const char *getGroupName() const;
386 
387   /*
388    *  get Character Set Options
389    *  Input :
390    *  Return : Character Set Options
391    */
392   const DcmQueryRetrieveCharacterSetOptions& getCharacterSetOptions() const;
393 
394   /*
395    *  get Character Set Options
396    *  Input :
397    *  Return : Character Set Options
398    */
399   DcmQueryRetrieveCharacterSetOptions& getCharacterSetOptions();
400 
401 private:
402 
403   friend struct DcmQueryRetrieveCharacterSetOptions;
404 
405   const char* vendorForPeerAETitle(const char *peerAETitle) const;
406 
407   int countCtnTitles() const;
408 
409 
410   /*
411    *  initialize configuration storage structure
412    */
413   void initConfigStruct();
414 
415   /*
416    *  read configuration file line by line
417    *  Input : configuration file pointer
418    *  Return : 1 - ok
419    *     0 - error
420    */
421   int readConfigLines(FILE *cnffp);
422 
423   /*
424    *  read HostTable in configuration file
425    *  Input : configuration file pointer, line number
426    *  Output : line number
427    *  Return : 1 - ok
428    *     0 - error
429    */
430   int readHostTable(FILE *cnffp, int *lineno);
431 
432   /*
433    *  read VendorTable in configuration file
434    *  Input : configuration file pointer, line number
435    *  Output : line number
436    *  Return : 1 - ok
437    *     0 - error
438    */
439   int readVendorTable(FILE *cnffp, int *lineno);
440 
441   /*
442    *  read AETable in configuration file
443    *  Input : configuration file pointer, line number
444    *  Output : line number
445    *  Return : 1 - ok
446    *     0 - error
447    */
448   int readAETable(FILE *cnffp, int *lineno);
449 
450   /*
451    *  separate the peer list from value list
452    *  Input : pointer to value list
453    *  Output : number of peers
454    *  Return : pointer to peer list
455    */
456   DcmQueryRetrieveConfigPeer *parsePeers(char **valuehandle, int *peers);
457 
458   /*
459    *  extract peers from peer list
460    *  Input : pointer to value list
461    *  Output : number of peers
462    *  Return : pointer to peer list
463    */
464   DcmQueryRetrieveConfigPeer *readPeerList(char **valuehandle, int *peers);
465 
466   /*
467    *  separate a quota from value list
468    *  Input : pointer to value list
469    *  Return : pointer to quota structure
470    */
471   static DcmQueryRetrieveConfigQuota *parseQuota(char **valuehandle);
472 
473   /*
474    *  check if character is white space or separator
475    *  Input : character
476    *  Return : 1 - yes
477    *     0 - no
478    */
479   static int isgap (char gap);
480 
481   /*
482    *  check if character is quote
483    *  Input : character
484    *  Return : 1 - yes
485    *     0 - no
486    */
487   static int isquote (char quote);
488 
489   /*
490    *  print a panic message to stderr
491    *  Input : variable
492    */
493   static void panic(const char *fmt, ...);
494 
495   /*
496    *  convert string to long
497    *  Input : parameter string value
498    *  Return : parameter as long
499    *     -1 on error
500    */
501   static long quota (const char *value);
502 
503   /*
504    *  skip mnemonic and first gap in rc line
505    *  Input : rc line
506    *  Return : pointer to value list
507    */
508   static char *skipmnemonic (char *rcline);
509 
510   /*
511    *  separate on value from value list
512    *  Input : pointer to value list
513    *  Return : pointer to next value
514    */
515   static char *parsevalues (char **valuehandle);
516 
517   /* Configuration Parameters */
518   OFString UserName_;
519   OFString GroupName_;
520   int networkTCPPort_;
521   Uint32 maxPDUSize_;
522   int maxAssociations_;
523   DcmQueryRetrieveCharacterSetOptions characterSetOptions_;
524   DcmQueryRetrieveConfigConfiguration CNF_Config;   /* configuration file contents */
525   DcmQueryRetrieveConfigHostTable CNF_HETable;      /* HostEntries Table */
526   DcmQueryRetrieveConfigHostTable CNF_VendorTable;  /* Vendor Table */
527 
528 };
529 
530 
531 #endif
532