1 // Copyright 2010-2018, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #ifndef MOZC_IPC_IPC_PATH_MANAGER_H_
31 #define MOZC_IPC_IPC_PATH_MANAGER_H_
32 
33 #ifdef OS_WIN
34 #include <time.h>  // for time_t
35 #else
36 #include <sys/time.h>  // for time_t
37 #endif  // OS_WIN
38 #ifdef OS_WIN
39 #include <map>
40 #endif  // OS_WIN
41 #include <memory>
42 #include <string>
43 
44 #include "base/mutex.h"
45 #include "base/port.h"
46 // For FRIEND_TEST
47 #include "testing/base/public/gunit_prod.h"
48 
49 namespace mozc {
50 
51 namespace ipc {
52 class IPCPathInfo;
53 }
54 
55 class ProcessMutex;
56 
57 class IPCPathManager {
58  public:
59   // Brief summary of CreateNew / Save / Load / Get PathName().
60   // CreateNewPathName: Generates a pathname and save it into the heap.
61   // SavePathName:      Saves a pathname into a file from the heap.
62   // LoadPathName:      Loads a pathname from a file and save it into the heap.
63   // GetPathName:       Sets a pathname on an argument using the heap.
64 
65   // Create new pathname and save it into the heap. If pathname is not empty,
66   // do nothing.
67   bool CreateNewPathName();
68 
69   // Save ipc path to ~/.mozc/.<name>.ipc
70   // if server_ipc_key_ is empty, CreateNewPathName() is called automatically.
71   // If the file is already locked, return false
72   bool SavePathName();
73 
74   // Load a pathname from a disk and updates |ipc_path_info_| if pathname is
75   // empty or ipc key file is updated. Returns false if it cannot load.
76   bool LoadPathName();
77 
78   // Get a pathanem from the heap. If pathanme is empty, returns false.
79   bool GetPathName(string *path_name) const;
80 
81   // return protocol version.
82   // return 0 if protocol version is not defined.
83   uint32 GetServerProtocolVersion() const;
84 
85   // return product version.
86   // return "0.0.0.0" if product version is not defined
87   const string &GetServerProductVersion() const;
88 
89   // return process id of the server
90   uint32 GetServerProcessId() const;
91 
92   // Checks the server pid is the valid server specified with server_path.
93   // server pid can be obtained by OS dependent method.
94   // This API is only available on Windows Vista or Linux.
95   // Due to the restriction of OpenProcess API, always returns true under
96   // AppContainer sandbox on Windows 8 (No verification will be done).
97   // Always returns true on other operating systems.
98   // See also: GetNamedPipeServerProcessId
99   // http://msdn.microsoft.com/en-us/library/aa365446.aspx
100   // when pid of 0 is passed, IsValidServer() returns true.
101   // when pid of static_cast<size_t>(-1) is passed, IsValidServer()
102   // returns false.
103   // To keep backward compatibility and other operationg system
104   // having no support of getting peer's pid, you can set 0 pid.
105   bool IsValidServer(uint32 pid, const string &server_path);
106 
107   // clear ipc_key;
108   void Clear();
109 
110   // return singleton instance corresponding to "name"
111   static IPCPathManager *GetIPCPathManager(const string &name);
112 
113   // do not call constructor directly.
114   explicit IPCPathManager(const string &name);
115   virtual ~IPCPathManager();
116 
117  private:
118   FRIEND_TEST(IPCPathManagerTest, ReloadTest);
119   FRIEND_TEST(IPCPathManagerTest, PathNameTest);
120 
121   bool LoadPathNameInternal();
122 
123   // Returns true if the ipc file is updated after it load.
124   bool ShouldReload() const;
125 
126   // Returns the last modified timestamp of the IPC file.
127   time_t GetIPCFileTimeStamp() const;
128 
129   std::unique_ptr<ProcessMutex> path_mutex_;   // lock ipc path file
130   std::unique_ptr<Mutex> mutex_;   // mutex for methods
131   std::unique_ptr<ipc::IPCPathInfo> ipc_path_info_;
132   string name_;
133   string server_path_;   // cache for server_path
134   uint32 server_pid_;    // cache for pid of server_path
135   time_t last_modified_;
136 #ifdef OS_WIN
137   std::map<string, std::wstring> expected_server_ntpath_cache_;
138 #endif  // OS_WIN
139 };
140 
141 }  // namespace mozc
142 
143 #endif  // MOZC_IPC_IPC_PATH_MANAGER_H_
144