1 /*
2  * lftp - file transfer program
3  *
4  * Copyright (c) 1996-2016 by Alexander V. Lukyanov (lav@yars.free.net)
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef RESMGR_H
21 #define RESMGR_H
22 
23 #include "trio.h"
24 #include <sys/types.h>
25 #include <time.h>
26 #include "TimeDate.h"
27 #include "xstring.h"
28 #include "xlist.h"
29 #include "xmap.h"
30 
31 typedef const char *ResValValid(xstring_c *value);
32 typedef const char *ResClValid(xstring_c *closure);
33 
34 class ResValue;
35 class ResMgr;
36 class Resource;
37 
38 struct ResType
39 {
40    static bool class_inited;
41    static xmap<ResType*> *types_by_name;
42 
43    const char *name;
44    const char *defvalue;
45    ResValValid *val_valid;
46    ResClValid *closure_valid;
47    xlist_head<Resource> *type_value_list;
48 
49    const char *SimpleQuery(const char *closure) const;
50    ResValue Query(const char *closure) const;
51    bool QueryBool(const char *closure) const;
52    bool QueryTriBool(const char *closure,bool a) const;
53 
54    bool IsAlias() const;
GetAliasTargetResType55    const char *GetAliasTarget() const { return defvalue; }
56 
57    const char *Set(const char *cclosure,const char *cvalue,bool def=false);
58    static const char *Set(const char *name,const char *closure,const char *value,bool def=false);
SetDefaultResType59    static const char *SetDefault(const char *name,const char *closure,const char *value)
60       { return Set(name,closure,value,true); }
61 
62    void Register();
63    void Unregister();
64 
65    static char *Format(bool with_defaults,bool only_defaults);
66    static char **Generator(void);
67 
68    static void ClassInit();
69    static void ClassCleanup();
70 
71    enum CmpRes {
72       EXACT_PREFIX=0x00,SUBSTR_PREFIX=0x01,
73       EXACT_NAME  =0x00,SUBSTR_NAME  =0x10,
74       DIFFERENT=-1
75    };
76    static int VarNameCmp(const char *name1,const char *name2);
77    static const char *FindVar(const char *name,const ResType **type,const char **re_closure=0);
78    static const char *FindVar(const char *name,ResType **type,const char **re_closure=0) { return FindVar(name,const_cast<const ResType **>(type),re_closure); }
79    static const ResType *FindRes(const char *name);
80 };
81 
82 class Resource
83 {
84    friend class ResMgr;
85    friend struct ResType;
86    static xlist_head<Resource> all_list;
87 
88    const ResType *type;
89    xstring_c value;
90    xstring_c closure;
91    bool def;
92 
93    xlist<Resource> all_node;
94    xlist<Resource> type_value_node;
95 
96    bool ClosureMatch(const char *cl_data);
97    void Format(xstring& buf) const;
98 
99    Resource(ResType *type,const char *closure,const char *value,bool def=false);
100 public:
101    ~Resource();
102 };
103 
104 class ResMgr : public ResType
105 {
106    ResMgr();
107 public:
108    static const char *QueryNext(const char *name,const char **closure,Resource **ptr);
109    static ResValue Query(const char *name,const char *closure);
110    static bool QueryBool(const char *name,const char *closure);
111    static bool QueryTriBool(const char *name,const char *closure,bool a);
112 
113    static const char *BoolValidate(xstring_c *value);
114    static const char *TriBoolValidate(xstring_c *value);
115    static const char *NumberValidate(xstring_c *value);
116    static const char *UNumberValidate(xstring_c *value);
117    static const char *FloatValidate(xstring_c *value);
118    static const char *TimeIntervalValidate(xstring_c *value);
119    static const char *RangeValidate(xstring_c *value);
120    static const char *ERegExpValidate(xstring_c *value);
121    static const char *IPv4AddrValidate(xstring_c *value);
122    static const char *IPv6AddrValidate(xstring_c *value);
123    static const char *UNumberPairValidate(xstring_c *value);
124    static const char *FileAccessible(xstring_c *value,int mode,bool want_dir=false);
125    static const char *FileReadable(xstring_c *value);
126    static const char *FileExecutable(xstring_c *value);
127    static const char *DirReadable(xstring_c *value);
128    static const char *FileCreatable(xstring_c *value);
129    static const char *CharsetValidate(xstring_c *value);
130    static const char *NoClosure(xstring_c *);
131    static const char *HasClosure(xstring_c *);
132    static bool str2bool(const char *value);
133    static const char *AliasValidate(xstring_c *);
134 
135    static int ResourceCompare(const Resource *a,const Resource *b);
136 };
137 
138 class ResDecl : public ResType
139 {
140 public:
141    ResDecl(const char *a_name,const char *a_defvalue,
142 	   ResValValid *a_val_valid,ResClValid *a_closure_valid=0);
~ResDecl()143    ~ResDecl() { Unregister(); }
144 };
145 class ResDecls
146 {
147    xarray<ResType*> r;
148 public:
149    ResDecls(ResType *array);
150    ResDecls(ResType *r1,ResType *r2,...);
151    ~ResDecls();
152 };
153 
154 class ResValue
155 {
156    const char *s;
157 public:
ResValue(const char * s_new)158    ResValue(const char *s_new)
159       {
160 	 s=s_new;
161       }
to_bool()162    bool to_bool() const
163       {
164 	 return ResMgr::str2bool(s);
165       }
166    bool to_tri_bool(bool a) const;
167    unsigned long long to_unumber(unsigned long long max) const;
168    long long to_number(long long min,long long max) const;
169    operator int() const;
170    operator long() const;
171    operator unsigned() const;
172    operator unsigned long() const;
173    operator double() const { return atof(s); }
174    operator float() const  { return atof(s); }
175    operator const char*() const
176       {
177 	 return s;
178       }
is_nil()179    bool is_nil() const { return s==0; }
is_empty()180    bool is_empty() const { return s==0 || *s==0; }
181    void ToNumberPair(int &a,int &b) const;
182 };
183 
184 class TimeIntervalR : public TimeInterval
185 {
186    const char *error_text;
187    void init(const char *);
188 public:
Set(const char * s)189    void Set(const char *s) { init(s); }
TimeIntervalR()190    TimeIntervalR() { error_text=0; }
TimeIntervalR(const char * s)191    TimeIntervalR(const char *s) : TimeInterval(0,0) { init(s); }
TimeIntervalR(ResValue r)192    TimeIntervalR(ResValue r) : TimeInterval(0,0) { init(r); }
TimeInterval(s,ms)193    TimeIntervalR(time_t s,int ms=0) : TimeInterval(s,ms) { error_text=0; }
TimeIntervalR(const TimeDiff & d)194    TimeIntervalR(const TimeDiff &d) : TimeInterval(d) { error_text=0; }
Error()195    bool Error() const { return error_text!=0; };
ErrorText()196    const char *ErrorText() const { return error_text; }
197 };
198 
199 class NumberPair
200 {
201 protected:
202    long long n1,n2;
203    bool no_n1,no_n2;
204    const char *error_text;
205    char sep;
206 
207    static const char *scale(long long *value,char suf);
208    long long parse1(const char *s);
209 
210    void init(char sep,const char *s);
211 
212 public:
NumberPair(char sep)213    NumberPair(char sep) { init(sep,0); }
NumberPair(char sep,const char * s)214    NumberPair(char sep,const char *s) { init(sep,s); }
215    void Set(const char *s);
Error()216    bool Error() { return error_text!=0; };
ErrorText()217    const char *ErrorText() { return error_text; }
N1()218    long long N1() { return n1; }
N2()219    long long N2() { return n2; }
HasN1()220    bool HasN1() { return !no_n1; }
HasN2()221    bool HasN2() { return !no_n2; }
222 };
223 class Range : public NumberPair
224 {
225 public:
226    Range(const char *s);
Match(long long n)227    bool Match(long long n) const { return (no_n1 || n>=n1) && (no_n2 || n<=n2); }
IsFull()228    bool IsFull() { return no_n1 && no_n2; }
229    long long Random();
230 };
231 
232 class ResClient
233 {
234    static xlist_head<ResClient> list;
235    xlist<ResClient> node;
236 protected:
ResPrefix()237    virtual const char *ResPrefix() const { return 0; }
ResClosure()238    virtual const char *ResClosure() const { return 0; }
Reconfig(const char *)239    virtual void Reconfig(const char *) {}
240    ResValue Query(const char *name,const char *closure=0) const;
241    bool QueryBool(const char *name,const char *closure=0) const;
242    bool QueryTriBool(const char *name,const char *closure,bool a) const;
243    ResClient();
244    virtual ~ResClient();
245 public:
246    static void ReconfigAll(const char *);
247 };
248 
249 #endif //RESMGR_H
250