00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00028 #ifndef _UCOMMON_STRING_H_
00029 #include <ucommon/string.h>
00030 #endif
00031
00032 #ifndef _UCOMMON_MEMORY_H_
00033 #include <ucommon/memory.h>
00034 #endif
00035
00036 #ifndef _UCOMMON_BUFFER_H_
00037 #include <ucommon/buffer.h>
00038 #endif
00039
00040 #ifndef _UCOMMON_SHELL_H_
00041 #define _UCOMMON_SHELL_H_
00042
00043 #ifdef _MSWINDOWS_
00044 #define INVALID_PID_VALUE INVALID_HANDLE_VALUE
00045 #else
00046 #define INVALID_PID_VALUE -1
00047 #endif
00048
00049 #ifdef ERR
00050 #undef ERR
00051 #endif
00052
00053 NAMESPACE_UCOMMON
00054
00062 class __EXPORT shell : public mempager
00063 {
00064 private:
00065 char **_argv;
00066 unsigned _argc;
00067 char *_argv0;
00068 char *_exedir;
00069 LinkedObject *_syms;
00070
00071 class __LOCAL args : public OrderedObject
00072 {
00073 public:
00074 char *item;
00075 };
00076
00077 class __LOCAL syms : public LinkedObject
00078 {
00079 public:
00080 const char *name;
00081 const char *value;
00082 };
00083
00089 void collapse(LinkedObject *first);
00090
00094 void set0(char *argv0);
00095
00096 public:
00100 typedef enum {NOARGS = 0, NOARGUMENT, INVARGUMENT, BADOPTION, OPTION_USED, BAD_VALUE, NUMERIC_SET} errmsg_t;
00101
00105 typedef enum {NONE = 0, CONSOLE_LOG, USER_LOG, SYSTEM_LOG, SECURITY_LOG} logmode_t;
00106
00110 typedef enum {FAIL = 0, ERR, WARN, NOTIFY, INFO, DEBUG0} loglevel_t;
00111
00115 typedef enum {NO_NUMERIC, NUMERIC_PLUS, NUMERIC_DASH, NUMERIC_ALL} numeric_t;
00116
00120 typedef enum {
00121 PROGRAM_CONFIG, SERVICE_CONFIG, USER_DEFAULTS, SERVICE_CONTROL,
00122 USER_HOME = USER_DEFAULTS + 3, SERVICE_DATA, SYSTEM_TEMP, USER_CACHE,
00123 SERVICE_CACHE, USER_DATA, USER_CONFIG, SYSTEM_CFG, SYSTEM_ETC,
00124 SYSTEM_VAR, SYSTEM_PREFIX, SYSTEM_SHARE, PROGRAM_PLUGINS,
00125 PROGRAM_TEMP} path_t;
00126
00130 typedef bool (*logproc_t)(loglevel_t level, const char *text);
00131
00135 typedef cpr_service_t mainproc_t;
00136
00140 typedef void (*exitproc_t)(void);
00141
00142 #ifdef _MSWINDOWS_
00143 typedef HANDLE pid_t;
00144 #else
00145
00148 typedef int pid_t;
00149 #endif
00150
00157 static const char *errmsg(errmsg_t id);
00158
00165 static void errmsg(errmsg_t id, const char *text);
00166
00173 class __EXPORT errormap
00174 {
00175 public:
00176 inline errormap(errmsg_t id, const char *text)
00177 {shell::errmsg(id, text);};
00178 };
00179
00187 class __EXPORT Option : public LinkedObject
00188 {
00189 public:
00190 char short_option;
00191 const char *long_option;
00192 const char *uses_option;
00193 const char *help_string;
00194 bool trigger_option;
00195
00203 Option(char short_option = 0, const char *long_option = NULL, const char *value_type = NULL, const char *help = NULL);
00204
00205 virtual ~Option();
00206
00207 static LinkedObject *first(void);
00208
00213 void disable(void);
00214
00220 virtual const char *assign(const char *value) = 0;
00221
00222 static void reset(void);
00223 };
00224
00232 class __EXPORT flagopt : public Option
00233 {
00234 private:
00235 unsigned counter;
00236 bool single;
00237
00238 virtual const char *assign(const char *value);
00239
00240 public:
00241 flagopt(char short_option, const char *long_option = NULL, const char *help = NULL, bool single_use = true);
00242
00243 inline operator bool()
00244 {return counter > 0;};
00245
00246 inline bool operator!()
00247 {return counter == 0;};
00248
00249 inline operator unsigned()
00250 {return counter;};
00251
00252 inline unsigned operator*()
00253 {return counter;};
00254
00255 inline void set(unsigned value = 1)
00256 {counter = value;};
00257 };
00258
00264 class __EXPORT groupopt : public Option
00265 {
00266 private:
00267 virtual const char *assign(const char *value);
00268
00269 public:
00270 groupopt(const char *help);
00271 };
00272
00279 class __EXPORT stringopt : public Option
00280 {
00281 private:
00282 bool used;
00283
00284 protected:
00285 const char *text;
00286
00287 virtual const char *assign(const char *value);
00288
00289 public:
00290 stringopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "text", const char *def_text = NULL);
00291
00292 inline void set(const char *string)
00293 {text = string;};
00294
00295 inline operator bool()
00296 {return used;};
00297
00298 inline bool operator!()
00299 {return !used;};
00300
00301 inline operator const char *()
00302 {return text;};
00303
00304 inline const char *operator*()
00305 {return text;};
00306 };
00307
00314 class __EXPORT charopt : public Option
00315 {
00316 private:
00317 bool used;
00318
00319 protected:
00320 char code;
00321
00322 virtual const char *assign(const char *value);
00323
00324 public:
00325 charopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "char", char default_code = ' ');
00326
00327 inline void set(char value)
00328 {code = value;};
00329
00330 inline operator bool()
00331 {return used;};
00332
00333 inline bool operator!()
00334 {return !used;};
00335
00336 inline operator char()
00337 {return code;};
00338
00339 inline char operator*()
00340 {return code;};
00341 };
00342
00349 class __EXPORT numericopt : public Option
00350 {
00351 private:
00352 bool used;
00353
00354 protected:
00355 long number;
00356
00357 virtual const char *assign(const char *value);
00358
00359 public:
00360 numericopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00361
00362 inline void set(long value)
00363 {number = value;};
00364
00365 inline operator bool()
00366 {return used;};
00367
00368 inline bool operator!()
00369 {return !used;};
00370
00371 inline operator long()
00372 {return number;};
00373
00374 inline long operator*()
00375 {return number;};
00376 };
00377
00386 class __EXPORT counteropt : public Option
00387 {
00388 private:
00389 bool used;
00390
00391 protected:
00392 long number;
00393
00394 virtual const char *assign(const char *value);
00395
00396 public:
00397 counteropt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00398
00399 inline void set(long value)
00400 {number = value;};
00401
00402 inline operator bool()
00403 {return used;};
00404
00405 inline bool operator!()
00406 {return !used;};
00407
00408 inline operator long()
00409 {return number;};
00410
00411 inline long operator*()
00412 {return number;};
00413 };
00414
00422 shell(const char *string, size_t pagesize = 0);
00423
00432 shell(int argc, char **argv, size_t pagesize = 0);
00433
00438 shell(size_t pagesize = 0);
00439
00440 static void setNumeric(numeric_t);
00441
00442 static long getNumeric(void);
00443
00447 static void help(void);
00448
00456 static int system(const char *command, const char **env = NULL);
00457
00464 static int systemf(const char *format, ...) __PRINTF(1,2);
00465
00470 static void relocate(const char *argv0);
00471
00478 static String path(path_t id);
00479
00484 static String userid(void);
00485
00492 static String path(path_t id, const char *directory);
00493
00499 static String path(String& prefix, const char *directory);
00500
00512 static void bind(const char *name);
00513
00523 static void rebind(const char *name = NULL);
00524
00530 char **parse(const char *string);
00531
00540 void parse(int argc, char **argv);
00541
00549 const char *env(const char *name, const char *value = NULL);
00550
00551 inline const char *getenv(const char *name, const char *value = NULL)
00552 {return env(name, value);}
00553
00560 const char *get(const char *name, const char *value = NULL);
00561
00562 inline const char *getsym(const char *name, const char *value = NULL)
00563 {return get(name, value);}
00564
00570 void set(const char *name, const char *value);
00571
00572 inline void setsym(const char *name, const char *value)
00573 {return set(name, value);}
00574
00580 bool is_sym(const char *name);
00581
00587 char *getargv0(char **argv);
00588
00596 char **getargv(char **argv);
00597
00604 void restart(char *argv0, char **argv, char **list);
00605
00609 inline const char *argv0() const
00610 {return _argv0;}
00611
00615 inline const char *execdir() const
00616 {return _exedir;}
00617
00622 static void error(const char *format, ...) __PRINTF(1, 2);
00623
00629 static void errexit(int exitcode, const char *format = NULL, ...) __PRINTF(2, 3);
00630
00631
00637 static inline int condition(bool test, int exitcode)
00638 { return (test) ? exitcode : 0;};
00639
00645 static void debug(unsigned level, const char *format, ...) __PRINTF(2, 3);
00646
00652 static void log(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
00653
00659 static void security(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
00660
00668 static void log(const char *name, loglevel_t level = ERR, logmode_t mode = USER_LOG, logproc_t handler = (logproc_t)NULL);
00669
00674 static size_t printf(const char *format, ...) __PRINTF(1, 2);
00675
00676 static size_t readln(char *address, size_t size);
00677
00678 static size_t writes(const char *string);
00679
00680 static size_t read(String& string);
00681
00682 inline static size_t write(String& string)
00683 {return writes(string.c_str());};
00684
00690 inline unsigned argc(void) const
00691 {return _argc;};
00692
00699 inline char **argv(void) const
00700 {return _argv;};
00701
00707 inline const char *operator[](unsigned offset)
00708 {return _argv[offset];};
00709
00710 static void exiting(exitproc_t);
00711
00715 void detach(mainproc_t mainentry = (mainproc_t)NULL);
00716
00720 void restart(void);
00721
00733 static shell::pid_t spawn(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00734
00743 static void priority(int pri = 1);
00744
00754 static int detach(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00755
00760 static void release(int exit_code = 0);
00761
00767 static int wait(shell::pid_t pid);
00768
00774 static int cancel(shell::pid_t pid);
00775
00780 inline unsigned operator()(void)
00781 {return _argc;};
00782
00795 static const char *text(const char *string);
00796
00806 static const char *texts(const char *singular, const char *plural, unsigned long count);
00807
00813 static unsigned count(char **argv);
00814
00815 #ifdef _MSWINDOWS_
00816
00817 static inline fd_t input(void)
00818 {return GetStdHandle(STD_INPUT_HANDLE);};
00819
00820 static inline fd_t output(void)
00821 {return GetStdHandle(STD_OUTPUT_HANDLE);};
00822
00823 static inline fd_t error(void)
00824 {return GetStdHandle(STD_ERROR_HANDLE);};
00825
00826 #else
00827 static inline fd_t input(void)
00828 {return 0;};
00829
00830 static inline fd_t output(void)
00831 {return 1;};
00832
00833 static inline fd_t error(void)
00834 {return 2;};
00835 #endif
00836
00837 static int inkey(const char *prompt = NULL);
00838
00839 static char *getpass(const char *prompt, char *buffer, size_t size);
00840
00841 static char *getline(const char *prompt, char *buffer, size_t size);
00842
00843 };
00844
00848 typedef shell shell_t;
00849
00853 #undef _TEXT
00854 #undef _STR
00855 #define _STR(x) (const char *)(x)
00856
00864 inline const char *_TEXT(const char *s)
00865 {return shell::text(s);}
00866
00867 END_NAMESPACE
00868
00869 #endif