Chris@57
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@57
|
2
|
Chris@57
|
3 /*
|
Chris@57
|
4 EasyMercurial
|
Chris@57
|
5
|
Chris@57
|
6 Based on HgExplorer by Jari Korhonen
|
Chris@57
|
7 Copyright (c) 2010 Jari Korhonen
|
Chris@57
|
8 Copyright (c) 2010 Chris Cannam
|
Chris@57
|
9 Copyright (c) 2010 Queen Mary, University of London
|
Chris@57
|
10
|
Chris@57
|
11 This program is free software; you can redistribute it and/or
|
Chris@57
|
12 modify it under the terms of the GNU General Public License as
|
Chris@57
|
13 published by the Free Software Foundation; either version 2 of the
|
Chris@57
|
14 License, or (at your option) any later version. See the file
|
Chris@57
|
15 COPYING included with this distribution for more information.
|
Chris@57
|
16 */
|
jtkorhonen@0
|
17
|
Chris@62
|
18 #include "common.h"
|
Chris@62
|
19 #include "debug.h"
|
jtkorhonen@0
|
20
|
Chris@62
|
21 #include <QFileInfo>
|
Chris@62
|
22 #include <QProcessEnvironment>
|
Chris@62
|
23 #include <QStringList>
|
Chris@77
|
24 #include <QDir>
|
jtkorhonen@0
|
25
|
Chris@62
|
26 #include <sys/types.h>
|
Chris@76
|
27
|
Chris@76
|
28 #ifdef Q_OS_WIN32
|
Chris@76
|
29 #define _WIN32_WINNT 0x0500
|
Chris@76
|
30 #include <windows.h>
|
Chris@76
|
31 #include <security.h>
|
Chris@76
|
32 #else
|
Chris@78
|
33 #include <errno.h>
|
Chris@62
|
34 #include <pwd.h>
|
Chris@78
|
35 #include <unistd.h>
|
Chris@76
|
36 #endif
|
Chris@62
|
37
|
Chris@62
|
38 QString findExecutable(QString name)
|
Chris@62
|
39 {
|
Chris@77
|
40 bool found = false;
|
Chris@62
|
41 if (name != "") {
|
Chris@62
|
42 if (name[0] != '/') {
|
Chris@77
|
43 #ifdef Q_OS_WIN32
|
Chris@77
|
44 QChar pathSep = ';';
|
Chris@77
|
45 #else
|
Chris@77
|
46 QChar pathSep = ':';
|
Chris@77
|
47 #endif
|
Chris@62
|
48 name = QFileInfo(name).fileName();
|
Chris@62
|
49 QString path =
|
Chris@62
|
50 QProcessEnvironment::systemEnvironment().value("PATH");
|
Chris@62
|
51 DEBUG << "findExecutable: seeking location for binary " << name
|
Chris@74
|
52 << ": system path is " << path << endl;
|
Chris@74
|
53 #ifndef Q_OS_WIN32
|
Chris@74
|
54 path = path + ":/usr/local/bin";
|
Chris@74
|
55 DEBUG << "... adding /usr/local/bin just in case (fix and add settings dlg please)"
|
Chris@74
|
56 << endl;
|
Chris@74
|
57 #endif
|
Chris@62
|
58 QStringList elements = path.split(pathSep, QString::SkipEmptyParts);
|
Chris@62
|
59 foreach (QString element, elements) {
|
Chris@77
|
60 QString full = QDir(element).filePath(name);
|
Chris@62
|
61 QFileInfo fi(full);
|
Chris@62
|
62 if (fi.exists() && fi.isFile() && fi.isExecutable()) {
|
Chris@62
|
63 name = full;
|
Chris@77
|
64 found = true;
|
Chris@62
|
65 break;
|
Chris@62
|
66 }
|
Chris@62
|
67 }
|
Chris@62
|
68 }
|
Chris@62
|
69 }
|
Chris@77
|
70 #ifdef Q_OS_WIN32
|
Chris@77
|
71 if (!found) {
|
Chris@77
|
72 if (!name.endsWith(".exe")) {
|
Chris@77
|
73 return findExecutable(name + ".exe");
|
Chris@77
|
74 }
|
Chris@77
|
75 }
|
Chris@77
|
76 #endif
|
Chris@62
|
77 return name;
|
Chris@62
|
78 }
|
Chris@62
|
79
|
jtkorhonen@0
|
80 QString getSystem()
|
jtkorhonen@0
|
81 {
|
jtkorhonen@0
|
82 #ifdef Q_WS_X11
|
jtkorhonen@0
|
83 return QString("Linux");
|
jtkorhonen@0
|
84 #endif
|
jtkorhonen@0
|
85
|
jtkorhonen@0
|
86 #ifdef Q_WS_MAC
|
jtkorhonen@0
|
87 return QString("Mac");
|
jtkorhonen@0
|
88 #endif
|
jtkorhonen@0
|
89
|
jtkorhonen@0
|
90 #ifdef Q_WS_WIN
|
jtkorhonen@0
|
91 return QString("Windows");
|
jtkorhonen@0
|
92 #endif
|
jtkorhonen@0
|
93
|
jtkorhonen@0
|
94 return QString("");
|
jtkorhonen@0
|
95 }
|
jtkorhonen@0
|
96
|
jtkorhonen@0
|
97 QString getHgDirName()
|
jtkorhonen@0
|
98 {
|
jtkorhonen@0
|
99 if (getSystem() == "Windows")
|
jtkorhonen@0
|
100 {
|
jtkorhonen@0
|
101 return QString(".hg\\");
|
jtkorhonen@0
|
102 }
|
jtkorhonen@0
|
103 else
|
jtkorhonen@0
|
104 {
|
jtkorhonen@0
|
105 return QString(".hg/");
|
jtkorhonen@0
|
106 }
|
jtkorhonen@0
|
107 }
|
jtkorhonen@0
|
108
|
Chris@62
|
109 #ifdef Q_OS_WIN32
|
Chris@62
|
110 QString getUserRealName()
|
Chris@62
|
111 {
|
Chris@76
|
112 TCHAR buf[1024];
|
Chris@76
|
113 long unsigned int maxlen = 1000;
|
Chris@62
|
114 LPTSTR info = buf;
|
jtkorhonen@0
|
115
|
Chris@76
|
116 if (!GetUserNameEx(NameDisplay, info, &maxlen)) {
|
Chris@76
|
117 DEBUG << "GetUserNameEx failed: " << GetLastError() << endl;
|
Chris@62
|
118 return "";
|
Chris@62
|
119 }
|
jtkorhonen@0
|
120
|
Chris@76
|
121 #ifdef UNICODE
|
Chris@76
|
122 return QString::fromUtf16((const unsigned short *)info);
|
Chris@76
|
123 #else
|
Chris@76
|
124 return QString::fromLocal8Bit(info);
|
Chris@76
|
125 #endif
|
Chris@62
|
126 }
|
luisf@71
|
127 #else
|
luisf@71
|
128 #ifdef Q_OS_MAC
|
Chris@62
|
129 // Nothing here: definition is in common_osx.mm
|
Chris@62
|
130 #else
|
Chris@62
|
131 QString getUserRealName()
|
Chris@62
|
132 {
|
Chris@62
|
133 const int maxlen = 1023;
|
Chris@62
|
134 char buf[maxlen + 2];
|
jtkorhonen@0
|
135
|
Chris@62
|
136 if (getlogin_r(buf, maxlen)) return "";
|
jtkorhonen@0
|
137
|
Chris@62
|
138 struct passwd *p = getpwnam(buf);
|
Chris@62
|
139 if (!p) return "";
|
Chris@62
|
140
|
Chris@62
|
141 QString s(p->pw_gecos);
|
Chris@62
|
142 if (s != "") s = s.split(',')[0];
|
Chris@62
|
143 return s;
|
Chris@62
|
144 }
|
Chris@62
|
145 #endif
|
luisf@71
|
146 #endif
|
jtkorhonen@0
|
147
|
Chris@78
|
148 void loseControllingTerminal()
|
Chris@78
|
149 {
|
Chris@78
|
150 #ifndef Q_OS_WIN32
|
Chris@78
|
151 pid_t sid;
|
Chris@78
|
152 switch (fork()) {
|
Chris@78
|
153 case 0:
|
Chris@78
|
154 sid = setsid();
|
Chris@78
|
155 if (sid != (pid_t)-1) {
|
Chris@78
|
156 DEBUG << "setsid() succeeded, session ID is " << sid << endl;
|
Chris@78
|
157 } else {
|
Chris@78
|
158 perror("setsid failed");
|
Chris@78
|
159 DEBUG << "setsid() failed (errno = " << errno << ")" << endl;
|
Chris@78
|
160 }
|
Chris@78
|
161 switch (fork()) {
|
Chris@78
|
162 case 0:
|
Chris@78
|
163 return;
|
Chris@78
|
164 case -1:
|
Chris@78
|
165 perror("fork failed");
|
Chris@78
|
166 DEBUG << "second fork failed (errno = " << errno << ")" << endl;
|
Chris@78
|
167 return;
|
Chris@78
|
168 default:
|
Chris@78
|
169 exit(0);
|
Chris@78
|
170 }
|
Chris@78
|
171 case -1:
|
Chris@78
|
172 perror("fork failed");
|
Chris@78
|
173 DEBUG << "fork failed (errno = " << errno << ")" << endl;
|
Chris@78
|
174 return;
|
Chris@78
|
175 default:
|
Chris@78
|
176 exit(0);
|
Chris@78
|
177 }
|
Chris@78
|
178 #endif
|
Chris@78
|
179 }
|
Chris@79
|
180
|
Chris@79
|
181 FolderStatus getFolderStatus(QString path)
|
Chris@79
|
182 {
|
Chris@79
|
183 QFileInfo fi(path);
|
Chris@79
|
184 if (fi.exists()) {
|
Chris@79
|
185 QDir dir(path);
|
Chris@79
|
186 if (!dir.exists()) { // returns false for files
|
Chris@79
|
187 return FolderIsFile;
|
Chris@79
|
188 }
|
Chris@79
|
189 if (QDir(dir.filePath(".hg")).exists()) {
|
Chris@79
|
190 return FolderHasRepo;
|
Chris@79
|
191 }
|
Chris@79
|
192 return FolderExists;
|
Chris@79
|
193 } else {
|
Chris@79
|
194 QDir parent = fi.dir();
|
Chris@79
|
195 if (parent.exists()) {
|
Chris@79
|
196 return FolderParentExists;
|
Chris@79
|
197 }
|
Chris@79
|
198 return FolderUnknown;
|
Chris@79
|
199 }
|
Chris@79
|
200 }
|
Chris@79
|
201
|
Chris@79
|
202 QString getContainingRepoFolder(QString path)
|
Chris@79
|
203 {
|
Chris@79
|
204 if (getFolderStatus(path) == FolderHasRepo) return "";
|
Chris@79
|
205
|
Chris@79
|
206 QFileInfo me(path);
|
Chris@79
|
207 QFileInfo parent(me.dir().absolutePath());
|
Chris@79
|
208
|
Chris@79
|
209 while (me != parent) {
|
Chris@79
|
210 QString parentPath = parent.filePath();
|
Chris@79
|
211 if (getFolderStatus(parentPath) == FolderHasRepo) {
|
Chris@79
|
212 return parentPath;
|
Chris@79
|
213 }
|
Chris@79
|
214 me = parent;
|
Chris@79
|
215 parent = me.dir().absolutePath();
|
Chris@79
|
216 }
|
Chris@79
|
217
|
Chris@79
|
218 return "";
|
Chris@79
|
219 }
|
Chris@79
|
220
|
Chris@79
|
221 QString xmlEncode(QString s)
|
Chris@79
|
222 {
|
Chris@79
|
223 s
|
Chris@79
|
224 .replace("&", "&")
|
Chris@79
|
225 .replace("<", "<")
|
Chris@79
|
226 .replace(">", ">")
|
Chris@79
|
227 .replace("\"", """)
|
Chris@79
|
228 .replace("'", "'");
|
Chris@79
|
229
|
Chris@79
|
230 return s;
|
Chris@79
|
231 }
|