UCommon
/usr/src/RPM/BUILD/ucommon-6.3.3/inc/ucommon/shell.h
Go to the documentation of this file.
00001 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
00002 // Copyright (C) 2015 Cherokees of Idaho.
00003 //
00004 // This file is part of GNU uCommon C++.
00005 //
00006 // GNU uCommon C++ is free software: you can redistribute it and/or modify
00007 // it under the terms of the GNU Lesser General Public License as published
00008 // by the Free Software Foundation, either version 3 of the License, or
00009 // (at your option) any later version.
00010 //
00011 // GNU uCommon C++ is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public License
00017 // along with GNU uCommon C++.  If not, see <http://www.gnu.org/licenses/>.
00018 
00029 #ifndef _UCOMMON_STRING_H_
00030 #include <ucommon/string.h>
00031 #endif
00032 
00033 #ifndef _UCOMMON_MEMORY_H_
00034 #include <ucommon/memory.h>
00035 #endif
00036 
00037 #ifndef _UCOMMON_BUFFER_H_
00038 #include <ucommon/buffer.h>
00039 #endif
00040 
00041 #ifndef _UCOMMON_SHELL_H_
00042 #define _UCOMMON_SHELL_H_
00043 
00044 #ifdef  _MSWINDOWS_
00045 #define INVALID_PID_VALUE   INVALID_HANDLE_VALUE
00046 #else
00047 #define INVALID_PID_VALUE   -1
00048 #endif
00049 
00050 #ifdef  ERR
00051 #undef  ERR
00052 #endif
00053 
00054 namespace ucommon {
00055 
00063 class __EXPORT shell : public mempager
00064 {
00065 private:
00066     char **_argv;
00067     unsigned _argc;
00068     char *_argv0;
00069     char *_exedir;
00070     LinkedObject *_syms;
00071 
00072     class __LOCAL args : public OrderedObject
00073     {
00074     public:
00075         char *item;
00076     };
00077 
00078     class __LOCAL syms : public LinkedObject
00079     {
00080     public:
00081         const char *name;
00082         const char *value;
00083     };
00084 
00090     void collapse(LinkedObject *first);
00091 
00095     void set0(char *argv0);
00096 
00097 public:
00101     typedef enum {NOARGS = 0, NOARGUMENT, INVARGUMENT, BADOPTION, OPTION_USED, BAD_VALUE, NUMERIC_SET} errmsg_t;
00102 
00106     typedef enum {NONE = 0, CONSOLE_LOG, USER_LOG, SYSTEM_LOG, SECURITY_LOG} logmode_t;
00107 
00111     typedef enum {FAIL = 0, ERR, WARN, NOTIFY, INFO, DEBUG0} loglevel_t;
00112 
00116     typedef enum {NO_NUMERIC, NUMERIC_PLUS, NUMERIC_DASH, NUMERIC_ALL} numeric_t;
00117 
00121     typedef enum {
00122         PROGRAM_CONFIG, SERVICE_CONFIG, USER_DEFAULTS, SERVICE_CONTROL,
00123         USER_HOME = USER_DEFAULTS + 3, SERVICE_DATA, SYSTEM_TEMP, USER_CACHE,
00124         SERVICE_CACHE, USER_DATA, USER_CONFIG, SYSTEM_CFG, SYSTEM_ETC,
00125         SYSTEM_VAR, SYSTEM_PREFIX, SYSTEM_SHARE, PROGRAM_PLUGINS,
00126         PROGRAM_TEMP} path_t;
00127 
00131     typedef bool (*logproc_t)(loglevel_t level, const char *text);
00132 
00136     typedef cpr_service_t   mainproc_t;
00137 
00141     typedef void (*exitproc_t)(void);
00142 
00143 #ifdef  _MSWINDOWS_
00144     typedef HANDLE pid_t;
00145 #else
00146 
00149     typedef int pid_t;
00150 #endif
00151 
00158     static const char *errmsg(errmsg_t id);
00159 
00166     static void errmsg(errmsg_t id, const char *text);
00167 
00174     class __EXPORT errormap
00175     {
00176     public:
00177         inline errormap(errmsg_t id, const char *text)
00178             {shell::errmsg(id, text);}
00179     };
00180 
00188     class __EXPORT Option : public LinkedObject
00189     {
00190     public:
00191         char short_option;
00192         const char *long_option;
00193         const char *uses_option;
00194         const char *help_string;
00195         bool trigger_option;
00196 
00204         Option(char short_option = 0, const char *long_option = NULL, const char *value_type = NULL, const char *help = NULL);
00205 
00206         virtual ~Option();
00207 
00208         static LinkedObject *first(void);
00209 
00214         void disable(void);
00215 
00221         virtual const char *assign(const char *value) = 0;
00222 
00223         static void reset(void);
00224     };
00225 
00233     class __EXPORT flagopt : public Option
00234     {
00235     private:
00236         unsigned counter;
00237         bool single;
00238 
00239         virtual const char *assign(const char *value);
00240 
00241     public:
00242         flagopt(char short_option, const char *long_option = NULL, const char *help = NULL, bool single_use = true);
00243 
00244         inline operator bool() const
00245             {return counter > 0;}
00246 
00247         inline bool operator!() const
00248             {return counter == 0;}
00249 
00250         inline operator unsigned() const
00251             {return counter;}
00252 
00253         inline unsigned operator*() const
00254             {return counter;}
00255 
00256         inline void set(unsigned value = 1)
00257             {counter = value;}
00258     };
00259 
00265     class __EXPORT groupopt : public Option
00266     {
00267     private:
00268         virtual const char *assign(const char *value);
00269 
00270     public:
00271         groupopt(const char *help);
00272     };
00273 
00280     class __EXPORT stringopt : public Option
00281     {
00282     private:
00283         bool used;
00284 
00285     protected:
00286         const char *text;
00287 
00288         virtual const char *assign(const char *value);
00289 
00290     public:
00291         stringopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "text", const char *def_text = NULL);
00292 
00293         inline void set(const char *string)
00294             {text = string;}
00295 
00296         inline operator bool() const
00297             {return used;}
00298 
00299         inline bool operator!() const
00300             {return !used;}
00301 
00302         inline operator const char *() const
00303             {return text;}
00304 
00305         inline const char *operator*() const
00306             {return text;}
00307     };
00308 
00315     class __EXPORT charopt : public Option
00316     {
00317     private:
00318         bool used;
00319 
00320     protected:
00321         char code;
00322 
00323         virtual const char *assign(const char *value);
00324 
00325     public:
00326         charopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "char", char default_code = ' ');
00327 
00328         inline void set(char value)
00329             {code = value;}
00330 
00331         inline operator bool() const
00332             {return used;}
00333 
00334         inline bool operator!() const
00335             {return !used;}
00336 
00337         inline operator char() const
00338             {return code;}
00339 
00340         inline char operator*() const
00341             {return code;}
00342     };
00343 
00350     class __EXPORT numericopt : public Option
00351     {
00352     private:
00353         bool used;
00354 
00355     protected:
00356         long number;
00357 
00358         virtual const char *assign(const char *value);
00359 
00360     public:
00361         numericopt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00362 
00363         inline void set(long value)
00364             {number = value;}
00365 
00366         inline operator bool() const
00367             {return used;}
00368 
00369         inline bool operator!() const
00370             {return !used;}
00371 
00372         inline operator long() const
00373             {return number;}
00374 
00375         inline long operator*() const
00376             {return number;}
00377     };
00378 
00387     class __EXPORT counteropt : public Option
00388     {
00389     private:
00390         bool used;
00391 
00392     protected:
00393         long number;
00394 
00395         virtual const char *assign(const char *value);
00396 
00397     public:
00398         counteropt(char short_option, const char *long_option = NULL, const char *help = NULL, const char *type = "numeric", long def_value = 0);
00399 
00400         inline void set(long value)
00401             {number = value;}
00402 
00403         inline operator bool() const
00404             {return used;}
00405 
00406         inline bool operator!() const
00407             {return !used;}
00408 
00409         inline operator long() const
00410             {return number;}
00411 
00412         inline long operator*() const
00413             {return number;}
00414     };
00415 
00423     shell(const char *string, size_t pagesize = 0);
00424 
00433     shell(int argc, char **argv, size_t pagesize = 0);
00434 
00439     shell(size_t pagesize = 0);
00440 
00441     static void setNumeric(numeric_t);
00442 
00443     static long getNumeric(void);
00444 
00448     static void help(void);
00449 
00457     static int system(const char *command, const char **env = NULL);
00458 
00465     static int systemf(const char *format, ...) __PRINTF(1,2);
00466 
00471     static void relocate(const char *argv0);
00472 
00479     static String path(path_t id);
00480 
00485     static String userid(void);
00486 
00493     static String path(path_t id, const char *directory);
00494 
00500     static String path(String& prefix, const char *directory);
00501 
00513     static void bind(const char *name);
00514 
00524     static void rebind(const char *name = NULL);
00525 
00531     char **parse(const char *string);
00532 
00541     void parse(int argc, char **argv);
00542 
00550     const char *env(const char *name, const char *value = NULL);
00551 
00552     inline const char *getenv(const char *name, const char *value = NULL)
00553         {return env(name, value);}
00554 
00561     const char *get(const char *name, const char *value = NULL);
00562 
00563     inline const char *getsym(const char *name, const char *value = NULL)
00564         {return get(name, value);}
00565 
00571     void set(const char *name, const char *value);
00572 
00573     inline void setsym(const char *name, const char *value)
00574         {return set(name, value);}
00575 
00581     bool is_sym(const char *name) const;
00582 
00588     char *getargv0(char **argv);
00589 
00597     char **getargv(char **argv);
00598 
00605     void restart(char *argv0, char **argv, char **list);
00606 
00610     inline const char *argv0() const
00611         {return _argv0;}
00612 
00616     inline const char *execdir() const
00617         {return _exedir;}
00618 
00623     static void error(const char *format, ...) __PRINTF(1, 2);
00624 
00630     static void errexit(int exitcode, const char *format = NULL, ...) __PRINTF(2, 3);
00631 
00632 
00638     static inline int condition(bool test, int exitcode)
00639         { return (test) ? exitcode : 0;}
00640 
00646     static void debug(unsigned level, const char *format, ...) __PRINTF(2, 3);
00647 
00653     static void log(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
00654 
00660     static void security(loglevel_t level, const char *format, ...) __PRINTF(2, 3);
00661 
00669     static void log(const char *name, loglevel_t level = ERR, logmode_t mode = USER_LOG, logproc_t handler = (logproc_t)NULL);
00670 
00675     static size_t printf(const char *format, ...) __PRINTF(1, 2);
00676 
00677     static size_t readln(char *address, size_t size);
00678 
00679     static size_t writes(const char *string);
00680 
00681     static size_t read(String& string);
00682 
00683     inline static size_t write(String& string)
00684         {return writes(string.c_str());}
00685 
00691     inline unsigned argc(void) const
00692         {return _argc;}
00693 
00700     inline char **argv(void) const
00701         {return _argv;}
00702 
00708     inline const char *operator[](unsigned offset)
00709         {return _argv[offset];}
00710 
00711     static void exiting(exitproc_t);
00712 
00716     void detach(mainproc_t mainentry = (mainproc_t)NULL);
00717 
00721     void restart(void);
00722 
00734     static shell::pid_t spawn(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00735 
00744     static void priority(int pri = 1);
00745 
00755     static int  detach(const char *path, char **argv, char **env = NULL, fd_t *stdio = NULL);
00756 
00761     static void release(int exit_code = 0);
00762 
00768     static int wait(shell::pid_t pid);
00769 
00775     static int cancel(shell::pid_t pid);
00776 
00781     inline unsigned operator()(void) const
00782         {return _argc;}
00783 
00796     static const char *text(const char *string);
00797 
00807     static const char *texts(const char *singular, const char *plural, unsigned long count);
00808 
00814     static unsigned count(char **argv);
00815 
00816 #ifdef  _MSWINDOWS_
00817 
00818     static inline fd_t input(void)
00819         {return GetStdHandle(STD_INPUT_HANDLE);}
00820 
00821     static inline fd_t output(void)
00822         {return GetStdHandle(STD_OUTPUT_HANDLE);}
00823 
00824     static inline fd_t error(void)
00825         {return GetStdHandle(STD_ERROR_HANDLE);}
00826 
00827 #else
00828     static inline fd_t input(void)
00829         {return 0;}
00830 
00831     static inline fd_t output(void)
00832         {return 1;}
00833 
00834     static inline fd_t error(void)
00835         {return 2;}
00836 #endif
00837 
00838     static int inkey(const char *prompt = NULL);
00839 
00840     static char *getpass(const char *prompt, char *buffer, size_t size);
00841 
00842     static char *getline(const char *prompt, char *buffer, size_t size);
00843 
00844 };
00845 
00849 typedef shell shell_t;
00850 
00854 #undef  _TEXT
00855 #undef  _STR
00856 #define _STR(x) (const char *)(x)
00857 
00865 inline  const char *_TEXT(const char *s)
00866     {return shell::text(s);}
00867 
00868 } // namespace ucommon
00869 
00870 #endif