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 NAMESPACE_UCOMMON
00050
00058 class __EXPORT shell : public mempager
00059 {
00060 private:
00061 char **_argv;
00062 unsigned _argc;
00063 char *_argv0;
00064 char *_exedir;
00065 LinkedObject *_syms;
00066
00067 class __LOCAL args : public OrderedObject
00068 {
00069 public:
00070 char *item;
00071 };
00072
00073 class __LOCAL syms : public LinkedObject
00074 {
00075 public:
00076 const char *name;
00077 const char *value;
00078 };
00079
00085 void collapse(LinkedObject *first);
00086
00090 void set0(char *argv0);
00091
00092 public:
00096 typedef enum {NOARGS = 0, NOARGUMENT, INVARGUMENT, BADOPTION, OPTION_USED, BAD_VALUE, NUMERIC_SET} errmsg_t;
00097
00101 typedef enum {NONE = 0, CONSOLE_LOG, USER_LOG, SYSTEM_LOG, SECURITY_LOG} logmode_t;
00102
00106 typedef enum {FAIL = 0, ERR, WARN, NOTIFY, INFO, DEBUG0} loglevel_t;
00107
00111 typedef enum {NO_NUMERIC, NUMERIC_PLUS, NUMERIC_DASH, NUMERIC_ALL} numeric_t;
00112
00116 typedef enum {
00117 PROGRAM_CONFIG, SERVICE_CONFIG, USER_DEFAULTS, SERVICE_CONTROL,
00118 USER_HOME = USER_DEFAULTS + 3, SERVICE_DATA, SYSTEM_TEMP, USER_CACHE,
00119 SERVICE_CACHE, USER_DATA, USER_CONFIG, SYSTEM_CFG, SYSTEM_ETC,
00120 SYSTEM_VAR, SYSTEM_PREFIX, SYSTEM_SHARE, PROGRAM_PLUGINS,
00121 PROGRAM_TEMP} path_t;
00122
00126 typedef bool (*logproc_t)(loglevel_t level, const char *text);
00127
00131 typedef cpr_service_t mainproc_t;
00132
00136 typedef void (*exitproc_t)(void);
00137
00138 #ifdef _MSWINDOWS_
00139 typedef HANDLE pid_t;
00140 #else
00141
00144 typedef int pid_t;
00145 #endif
00146
00150 typedef enum {RD = BufferProtocol::BUF_RD, WR = BufferProtocol::BUF_WR, RDWR = BufferProtocol::BUF_RDWR} pmode_t;
00151
00160 class __EXPORT pipeio
00161 {
00162 protected:
00163 friend class shell;
00164
00168 pipeio();
00169
00179 int spawn(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00180
00185 int wait(void);
00186
00192 int cancel(void);
00193
00202 size_t read(void *address, size_t size);
00203
00212 size_t write(const void *address, size_t size);
00213
00214 pid_t pid;
00215 fd_t input, output;
00216 int perror, presult;
00217 };
00218
00225 class __EXPORT iobuf : public BufferProtocol, private pipeio
00226 {
00227 protected:
00228 friend class shell;
00229
00230 int ioerror;
00231
00232 virtual int _err(void) const;
00233 virtual void _clear(void);
00234
00235 virtual size_t _push(const char *address, size_t size);
00236 virtual size_t _pull(char *address, size_t size);
00237
00238 public:
00244 iobuf(size_t size = 0);
00245
00256 iobuf(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00257
00262 ~iobuf();
00263
00272 void open(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00273
00278 void close(void);
00279
00284 void cancel(void);
00285 };
00286
00290 typedef iobuf io_t;
00291
00295 typedef pipeio *pipe_t;
00296
00303 static const char *errmsg(errmsg_t id);
00304
00311 static void errmsg(errmsg_t id, const char *text);
00312
00319 class __EXPORT errormap
00320 {
00321 public:
00322 inline errormap(errmsg_t id, const char *text)
00323 {shell::errmsg(id, text);};
00324 };
00325
00333 class __EXPORT Option : public OrderedObject
00334 {
00335 public:
00336 char short_option;
00337 const char *long_option;
00338 const char *uses_option;
00339 const char *help_string;
00340 bool trigger_option;
00341
00349 Option(char short_option = 0, const char *long_option = NULL, const char *value_type = NULL, const char *help = NULL);
00350
00351 virtual ~Option();
00352
00353 static LinkedObject *first(void);
00354
00359 void disable(void);
00360
00366 virtual const char *assign(const char *value) = 0;
00367
00368 static void reset(void);
00369 };
00370
00378 class __EXPORT flagopt : public Option
00379 {
00380 private:
00381 unsigned counter;
00382 bool single;
00383
00384 virtual const char *assign(const char *value);
00385
00386 public:
00387 flagopt(char short_option, const char *long_option = NULL, const char *help = NULL, bool single_use = true);
00388
00389 inline operator bool()
00390 {return counter > 0;};
00391
00392 inline bool operator!()
00393 {return counter == 0;};
00394
00395 inline operator unsigned()
00396 {return counter;};
00397
00398 inline unsigned operator*()
00399 {return counter;};
00400
00401 inline void set(unsigned value = 1)
00402 {counter = value;};
00403 };
00404
00410 class __EXPORT groupopt : public Option
00411 {
00412 private:
00413 virtual const char *assign(const char *value);
00414
00415 public:
00416 groupopt(const char *help);
00417 };
00418
00425 class __EXPORT stringopt : public Option
00426 {
00427 private:
00428 bool used;
00429
00430 protected:
00431 const char *text;
00432
00433 virtual const char *assign(const char *value);
00434
00435 public:
00436 stringopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "text", const char *def_text = NULL);
00437
00438 inline void set(const char *string)
00439 {text = string;};
00440
00441 inline operator bool()
00442 {return used;};
00443
00444 inline bool operator!()
00445 {return !used;};
00446
00447 inline operator const char *()
00448 {return text;};
00449
00450 inline const char *operator*()
00451 {return text;};
00452 };
00453
00460 class __EXPORT charopt : public Option
00461 {
00462 private:
00463 bool used;
00464
00465 protected:
00466 char code;
00467
00468 virtual const char *assign(const char *value);
00469
00470 public:
00471 charopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "char", char default_code = ' ');
00472
00473 inline void set(char value)
00474 {code = value;};
00475
00476 inline operator bool()
00477 {return used;};
00478
00479 inline bool operator!()
00480 {return !used;};
00481
00482 inline operator char()
00483 {return code;};
00484
00485 inline char operator*()
00486 {return code;};
00487 };
00488
00495 class __EXPORT numericopt : public Option
00496 {
00497 private:
00498 bool used;
00499
00500 protected:
00501 long number;
00502
00503 virtual const char *assign(const char *value);
00504
00505 public:
00506 numericopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00507
00508 inline void set(long value)
00509 {number = value;};
00510
00511 inline operator bool()
00512 {return used;};
00513
00514 inline bool operator!()
00515 {return !used;};
00516
00517 inline operator long()
00518 {return number;};
00519
00520 inline long operator*()
00521 {return number;};
00522 };
00523
00532 class __EXPORT counteropt : public Option
00533 {
00534 private:
00535 bool used;
00536
00537 protected:
00538 long number;
00539
00540 virtual const char *assign(const char *value);
00541
00542 public:
00543 counteropt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00544
00545 inline void set(long value)
00546 {number = value;};
00547
00548 inline operator bool()
00549 {return used;};
00550
00551 inline bool operator!()
00552 {return !used;};
00553
00554 inline operator long()
00555 {return number;};
00556
00557 inline long operator*()
00558 {return number;};
00559 };
00560
00568 shell(const char *string, size_t pagesize = 0);
00569
00578 shell(int argc, char **argv, size_t pagesize = 0);
00579
00584 shell(size_t pagesize = 0);
00585
00586 static void setNumeric(numeric_t);
00587
00588 static long getNumeric(void);
00589
00593 static void help(void);
00594
00602 static int system(const char *command, const char **env = NULL);
00603
00610 static int systemf(const char *format, ...) __PRINTF(1,2);
00611
00616 static void relocate(const char *argv0);
00617
00624 static String path(path_t id);
00625
00630 static String userid(void);
00631
00638 static String path(path_t id, const char *directory);
00639
00645 static String path(String& prefix, const char *directory);
00646
00658 static void bind(const char *name);
00659
00669 static void rebind(const char *name = NULL);
00670
00676 char **parse(const char *string);
00677
00686 void parse(int argc, char **argv);
00687
00695 const char *getenv(const char *name, const char *value = NULL);
00696
00703 const char *getsym(const char *name, const char *value = NULL);
00704
00710 void setsym(const char *name, const char *value);
00711
00717 bool issym(const char *name);
00718
00724 char *getargv0(char **argv);
00725
00733 char **getargv(char **argv);
00734
00741 void restart(char *argv0, char **argv, char **list);
00742
00749 inline static char **parse(shell &args, const char *string)
00750 {return args.parse(string);}
00751
00755 inline const char *argv0() const
00756 {return _argv0;}
00757
00761 inline const char *execdir() const
00762 {return _exedir;}
00763
00769 static void errexit(int exitcode, const char *format = NULL, ...) __PRINTF(2, 3);
00770
00776 static void debug(unsigned level, const char *format, ...) __PRINTF(2, 3);
00777
00783 static void log(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
00784
00790 static void security(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
00791
00799 static void log(const char *name, loglevel_t level = ERR, logmode_t mode = USER_LOG, logproc_t handler = (logproc_t)NULL);
00800
00805 static size_t printf(const char *format, ...) __PRINTF(1, 2);
00806
00807 static size_t readln(char *address, size_t size);
00808
00809 static size_t writes(const char *string);
00810
00811 static size_t read(String& string);
00812
00813 inline static size_t write(String& string)
00814 {return writes(string.c_str());};
00815
00822 static size_t printf(pipe_t pipe, const char *format, ...) __PRINTF(2, 3);
00823
00831 static size_t readln(pipe_t pipe, char *buffer, size_t size);
00832
00833 static size_t read(pipe_t pipe, String& string);
00834
00835 static size_t writes(pipe_t pipe, const char *string);
00836
00837 inline static size_t write(pipe_t pipe, String& string)
00838 {return writes(pipe, string.c_str());};
00839
00845 inline unsigned argc(void) const
00846 {return _argc;};
00847
00854 inline char **argv(void) const
00855 {return _argv;};
00856
00862 inline const char *operator[](unsigned offset)
00863 {return _argv[offset];};
00864
00865 static void exiting(exitproc_t);
00866
00870 void detach(mainproc_t mainentry = (mainproc_t)NULL);
00871
00875 void restart(void);
00876
00888 static shell::pid_t spawn(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00889
00901 static shell::pipe_t spawn(const char *path, char **argv, pmode_t mode, size_t size = 512, char **env = NULL);
00902
00911 static void priority(int pri = 1);
00912
00922 static int detach(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00923
00929 static int wait(shell::pid_t pid);
00930
00936 static int cancel(shell::pid_t pid);
00937
00944 static int wait(shell::pipe_t pointer);
00945
00951 static int cancel(shell::pipe_t pointer);
00952
00957 inline unsigned operator()(void)
00958 {return _argc;};
00959
00972 static const char *text(const char *string);
00973
00983 static const char *texts(const char *singular, const char *plural, unsigned long count);
00984
00990 static unsigned count(char **argv);
00991
00992 #ifdef _MSWINDOWS_
00993
00994 static inline fd_t input(void)
00995 {return GetStdHandle(STD_INPUT_HANDLE);};
00996
00997 static inline fd_t output(void)
00998 {return GetStdHandle(STD_OUTPUT_HANDLE);};
00999
01000 static inline fd_t error(void)
01001 {return GetStdHandle(STD_ERROR_HANDLE);};
01002
01003 #else
01004 static inline fd_t input(void)
01005 {return 0;};
01006
01007 static inline fd_t output(void)
01008 {return 1;};
01009
01010 static inline fd_t error(void)
01011 {return 2;};
01012 #endif
01013
01014 static int inkey(const char *prompt = NULL);
01015
01016 static char *getpass(const char *prompt, char *buffer, size_t size);
01017
01018 static char *getline(const char *prompt, char *buffer, size_t size);
01019
01020 };
01021
01025 typedef shell shell_t;
01026
01030 #undef _TEXT
01031 #undef _STR
01032
01040 inline const char *_TEXT(const char *s)
01041 {return shell::text(s);}
01042
01043 inline const char *_STR(String& s)
01044 {return *s;}
01045
01046 END_NAMESPACE
01047
01048 #endif