1/*
2 * Python bindings.
3 *
4 * Open Phone Abstraction Library (OPAL)
5 *
6 * Copyright (c) 2011 Demetrius Cassidy
7 *
8 * The contents of this file are subject to the Mozilla Public License
9 * Version 1.0 (the "License"); you may not use this file except in
10 * compliance with the License. You may obtain a copy of the License at
11 * http://www.mozilla.org/MPL/
12 *
13 * Software distributed under the License is distributed on an "AS IS"
14 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
15 * the License for the specific language governing rights and limitations
16 * under the License.
17 *
18 * The Original Code is Open Phone Abstraction Library (OPAL)
19 *
20 * The Initial Developer of the Original Code is Demetrius Cassidy
21 *
22 * Contributor(s): ______________________________________.
23 *
24 * $Revision: 26117 $
25 * $Author: rjongbloed $
26 * $Date: 2011-07-04 22:45:05 -0500 (Mon, 04 Jul 2011) $
27 */
28
29///////////////////////////////////////////////////////////////////////////////
30// PProcess
31
32/**This class represents an operating system process. This is a running
33   "programme" in the  context of the operating system. Note that there can
34   only be one instance of a PProcess class in a given programme.
35
36   The instance of a PProcess or its GUI descendent <code>PApplication</code> is
37   usually a static variable created by the application writer. This is the
38   initial "anchor" point for all data structures in an application. As the
39   application writer never needs to access the standard system
40   <code>main()</code> function, it is in the library, the programmes
41   execution begins with the virtual function <code>PThread::Main()</code> on a
42   process.
43 */
44class PProcess : PThread
45{
46
47  public:
48  /**@name Construction */
49  //@{
50    /// Release status for the program.
51    enum CodeStatus {
52      /// Code is still very much under construction.
53      AlphaCode,
54      /// Code is largely complete and is under test.
55      BetaCode,
56      /// Code has all known bugs removed and is shipping.
57      ReleaseCode,
58      NumCodeStatuses
59    };
60
61    /** Create a new process instance.
62     */
63    PProcess(
64      const char * manuf = "",         ///< Name of manufacturer
65      const char * name = "",          ///< Name of product
66      WORD majorVersion = 1,           ///< Major version number of the product
67      WORD minorVersion = 0,           ///< Minor version number of the product
68      CodeStatus status = ReleaseCode, ///< Development status of the product
69      WORD buildNumber = 1,            ///< Build number of the product
70      bool library = false             ///< PProcess is a library rather than an application
71    );
72  //@}
73
74  /**@name Overrides from class PObject */
75  //@{
76    /**Compare two process instances. This should almost never be called as
77       a programme only has access to a single process, its own.
78
79       @return
80       <code>EqualTo</code> if the two process object have the same name.
81     */
82    Comparison Compare(
83      const PObject & obj   ///< Other process to compare against.
84    ) const;
85  //@}
86
87  /**@name Overrides from class PThread */
88  //@{
89    /**Terminate the process. Usually only used in abnormal abort situation.
90     */
91    virtual void Terminate();
92
93    /** Get the name of the thread. Thread names are a optional debugging aid.
94
95       @return
96       current thread name.
97     */
98    virtual PString GetThreadName() const;
99
100    /** Change the name of the thread. Thread names are a optional debugging aid.
101
102       @return
103       current thread name.
104     */
105    virtual void SetThreadName(
106      const PString & name        ///< New name for the thread.
107    );
108  //@}
109
110  /**@name Process information functions */
111  //@{
112    /**Get the current processes object instance. The <i>current process</i>
113       is the one the application is running in.
114
115       @return
116       pointer to current process instance.
117     */
118    static PProcess & Current();
119
120    /**Callback for when a thread is started by the PTLib system. Note this is
121       called in the context of the new thread.
122      */
123    virtual void OnThreadStart(
124      PThread & thread
125    );
126
127    /**Callback for when a thread is ended if wqas started in the PTLib system.
128       Note this is called in the context of the old thread.
129      */
130    virtual void OnThreadEnded(
131      PThread & thread
132    );
133
134    /**Callback for when a ^C (SIGINT) or termination request (SIGTERM) is
135       received by process.
136
137       Note this function is called asynchronously and there may be many
138       limitations on what can and cannot be done depending on the underlying
139       operating system. It is recommeneded that this does no more than set
140       flags and return.
141
142       Default behaviour returns false and the process is killed.
143
144       @return true if the process is to be allowed to continue, false otherwise.
145      */
146    virtual bool OnInterrupt(
147      bool terminating ///< true if process terminating.
148    );
149
150    /**Determine if the current processes object instance has been initialised.
151       If this returns true it is safe to use the PProcess::Current() function.
152
153       @return
154       true if process class has been initialised.
155     */
156    static PBoolean IsInitialised();
157
158    /**Set the termination value for the process.
159
160       The termination value is an operating system dependent integer which
161       indicates the processes termiantion value. It can be considered a
162       "return value" for an entire programme.
163     */
164    void SetTerminationValue(
165      int value  ///< Value to return a process termination status.
166    );
167
168    /**Get the termination value for the process.
169
170       The termination value is an operating system dependent integer which
171       indicates the processes termiantion value. It can be considered a
172       "return value" for an entire programme.
173
174       @return
175       integer termination value.
176     */
177    int GetTerminationValue() const;
178
179    /**Get the programme arguments. Programme arguments are a set of strings
180       provided to the programme in a platform dependent manner.
181
182       @return
183       argument handling class instance.
184     */
185    PArgList & GetArguments();
186
187    /**Get the name of the manufacturer of the software. This is used in the
188       default "About" dialog box and for determining the location of the
189       configuration information as used by the <code>PConfig</code> class.
190
191       The default for this information is the empty string.
192
193       @return
194       string for the manufacturer name eg "Equivalence".
195     */
196    virtual const PString & GetManufacturer() const;
197
198    /**Get the name of the process. This is used in the
199       default "About" dialog box and for determining the location of the
200       configuration information as used by the <code>PConfig</code> class.
201
202       The default is the title part of the executable image file.
203
204       @return
205       string for the process name eg "MyApp".
206     */
207    virtual const PString & GetName() const;
208
209    /**Get the version of the software. This is used in the default "About"
210       dialog box and for determining the location of the configuration
211       information as used by the <code>PConfig</code> class.
212
213       If the <code>full</code> parameter is true then a version string
214       built from the major, minor, status and build veriosn codes is
215       returned. If false then only the major and minor versions are
216       returned.
217
218       The default for this information is "1.0".
219
220       @return
221       string for the version eg "1.0b3".
222     */
223    virtual PString GetVersion(
224      PBoolean full = true ///< true for full version, false for short version.
225    ) const;
226
227    /**Get the processes executable image file path.
228
229       @return
230       file path for program.
231     */
232    const PFilePath & GetFile() const;
233
234    /**Get the platform dependent process identifier for the process. This is
235       an arbitrary (and unique) integer attached to a process by the operating
236       system.
237
238       @return
239       Process ID for process.
240     */
241    DWORD GetProcessID() const;
242
243    /**Return the time at which the program was started
244    */
245    PTime GetStartTime() const;
246
247    /**Get the effective user name of the owner of the process, eg "root" etc.
248       This is a platform dependent string only provided by platforms that are
249       multi-user. Note that some value may be returned as a "simulated" user.
250       For example, in MS-DOS an environment variable
251
252       @return
253       user name of processes owner.
254     */
255    PString GetUserName() const;
256
257    /**Set the effective owner of the process.
258       This is a platform dependent string only provided by platforms that are
259       multi-user.
260
261       For unix systems if the username may consist exclusively of digits and
262       there is no actual username consisting of that string then the numeric
263       uid value is used. For example "0" is the superuser. For the rare
264       occassions where the users name is the same as their uid, if the
265       username field starts with a '#' then the numeric form is forced.
266
267       If an empty string is provided then original user that executed the
268       process in the first place (the real user) is set as the effective user.
269
270       The permanent flag indicates that the user will not be able to simple
271       change back to the original user as indicated above, ie for unix
272       systems setuid() is used instead of seteuid(). This is not necessarily
273       meaningful for all platforms.
274
275       @return
276       true if processes owner changed. The most common reason for failure is
277       that the process does not have the privilege to change the effective user.
278      */
279    PBoolean SetUserName(
280      const PString & username, ///< New user name or uid
281      PBoolean permanent = false    ///< Flag for if effective or real user
282    );
283
284    /**Get the effective group name of the owner of the process, eg "root" etc.
285       This is a platform dependent string only provided by platforms that are
286       multi-user. Note that some value may be returned as a "simulated" user.
287       For example, in MS-DOS an environment variable
288
289       @return
290       group name of processes owner.
291     */
292    PString GetGroupName() const;
293
294    /**Set the effective group of the process.
295       This is a platform dependent string only provided by platforms that are
296       multi-user.
297
298       For unix systems if the groupname may consist exclusively of digits and
299       there is no actual groupname consisting of that string then the numeric
300       uid value is used. For example "0" is the superuser. For the rare
301       occassions where the groups name is the same as their uid, if the
302       groupname field starts with a '#' then the numeric form is forced.
303
304       If an empty string is provided then original group that executed the
305       process in the first place (the real group) is set as the effective
306       group.
307
308       The permanent flag indicates that the group will not be able to simply
309       change back to the original group as indicated above, ie for unix
310       systems setgid() is used instead of setegid(). This is not necessarily
311       meaningful for all platforms.
312
313       @return
314       true if processes group changed. The most common reason for failure is
315       that the process does not have the privilege to change the effective
316       group.
317      */
318    PBoolean SetGroupName(
319      const PString & groupname, ///< New group name or gid
320      PBoolean permanent = false     ///< Flag for if effective or real group
321    );
322
323    /**Get the maximum file handle value for the process.
324       For some platforms this is meaningless.
325
326       @return
327       user name of processes owner.
328     */
329    int GetMaxHandles() const;
330
331    /**Set the maximum number of file handles for the process.
332       For unix systems the user must be run with the approriate privileges
333       before this function can set the value above the system limit.
334
335       For some platforms this is meaningless.
336
337       @return
338       true if successfully set the maximum file hadles.
339      */
340    PBoolean SetMaxHandles(
341      int newLimit  ///< New limit on file handles
342    );
343
344    /**Get the default file to use in PConfig instances.
345      */
346    virtual PString GetConfigurationFile();
347
348    /**Set the default file or set of directories to search for use in PConfig.
349       To find the .ini file for use in the default PConfig() instance, this
350       explicit filename is used, or if it is a set of directories separated
351       by either ':' or ';' characters, then the application base name postfixed
352       with ".ini" is searched for through those directories.
353
354       The search is actually done when the GetConfigurationFile() is called,
355       this function only sets the internal variable.
356
357       Note for Windows, a path beginning with "HKEY_LOCAL_MACHINE\\" or
358       "HKEY_CURRENT_USER\\" will actually search teh system registry for the
359       application base name only (no ".ini") in that folder of the registry.
360      */
361    void SetConfigurationPath(
362      const PString & path   ///< Explicit file or set of directories
363    );
364  //@}
365
366  /**@name Operating System information functions */
367  //@{
368    /**Get the class of the operating system the process is running on, eg
369       "unix".
370
371       @return
372       String for OS class.
373     */
374    static PString GetOSClass();
375
376    /**Get the name of the operating system the process is running on, eg
377       "Linux".
378
379       @return
380       String for OS name.
381     */
382    static PString GetOSName();
383
384    /**Get the hardware the process is running on, eg "sparc".
385
386       @return
387       String for OS name.
388     */
389    static PString GetOSHardware();
390
391    /**Get the version of the operating system the process is running on, eg
392       "2.0.33".
393
394       @return
395       String for OS version.
396     */
397    static PString GetOSVersion();
398
399    /**See if operating system is later than the version specified.
400
401       @return
402       true if OS version leter than or equal to parameters.
403     */
404    static bool IsOSVersion(
405      unsigned major,     ///< Major version number
406      unsigned minor = 0, ///< Minor version number
407      unsigned build = 0  ///< Build number
408    );
409
410    /**Get the configuration directory of the operating system the process is
411       running on, eg "/etc" for Unix, "c:\windows" for Win95 or
412       "c:\winnt\system32\drivers\etc" for NT.
413
414       @return
415       Directory for OS configuration files.
416     */
417    static PDirectory GetOSConfigDir();
418
419    /**Get the version of the PTLib library the process is running on, eg
420       "2.5beta3".
421
422       @return
423       String for library version.
424     */
425    static PString GetLibVersion();
426  //@}
427
428    /**Internal initialisation function called directly from
429       <code>InternalMain()</code>. The user should never call this function.
430     */
431    void PreInitialise(
432      int argc,     // Number of program arguments.
433      char ** argv, // Array of strings for program arguments.
434      char ** envp  // Array of string for the system environment
435    );
436
437    /**Internal shutdown function called directly from the ~PProcess
438       <code>InternalMain()</code>. The user should never call this function.
439     */
440    static void PreShutdown();
441    static void PostShutdown();
442
443    /// Main function for process, called from real main after initialisation
444    virtual int InternalMain(void * arg = NULL);
445
446    /**@name Operating System URL manager functions */
447    /**
448        This class can be used to register various URL types with the host operating system
449        so that URLs will automatically launch the correct application.
450
451        The simplest way to use these functions is to add the code similar to the following
452        to the Main function of the PProcess descendant
453
454            PString urlTypes("sip\nh323\nsips\nh323s");
455            if (!PProcess::HostSystemURLHandlerInfo::RegisterTypes(urlTypes, false))
456              PProcess::HostSystemURLHandlerInfo::RegisterTypes(urlTypes, true);
457
458        This will check to see if the URL types sip, h323, sips and h323s are registered
459        with the operating system to launch the current application. If they are not, it
460        will rewrite the system configuraton so that they will.
461
462        For more information on the Windows implementation, see the following link:
463
464              http://msdn2.microsoft.com/en-us/library/aa767914.aspx
465      */
466    //@{
467    class HostSystemURLHandlerInfo
468    {
469      public:
470        HostSystemURLHandlerInfo();
471
472        HostSystemURLHandlerInfo(const PString & t);
473
474        static bool RegisterTypes(const PString & types, bool force = true);
475
476        void SetIcon(const PString & icon);
477        PString GetIcon() const;
478
479        void SetCommand(const PString & key, const PString & command);
480        PString GetCommand(const PString & key) const;
481
482        bool GetFromSystem();
483        bool CheckIfRegistered();
484
485        bool Register();
486
487        PString type;
488
489        PString iconFileName;
490        PStringToString cmds;
491    };
492  //@}
493
494
495// Include platform dependent part of class
496 public:
497    ~PProcess();
498
499    bool SignalTimerChange();
500    // Signal to the timer thread that a change was made.
501
502    virtual PBoolean IsServiceProcess() const;
503    virtual PBoolean IsGUIProcess() const;
504    void WaitOnExitConsoleWindow();
505};
506
507
508/** Class for a process that is a dynamically loaded library.
509 */
510 class PLibraryProcess : PProcess
511 {
512
513  public:
514  /**@name Construction */
515  //@{
516    /** Create a new process instance.
517     */
518    PLibraryProcess(
519      const char * manuf = "",         ///< Name of manufacturer
520      const char * name = "",          ///< Name of product
521      WORD majorVersionNum = 1,           ///< Major version number of the product
522      WORD minorVersionNum = 0,           ///< Minor version number of the product
523      CodeStatus statusCode = ReleaseCode, ///< Development status of the product
524      WORD buildNum = 1             ///< Build number of the product
525    );
526  //@}
527
528    ///< Dummy Main() as libraries do not have one.
529    virtual void Main();
530};
531