comparison src/common.cpp @ 370:b9c153e00e84

Move source files to src/
author Chris Cannam
date Thu, 24 Mar 2011 10:27:51 +0000
parents common.cpp@8fd71f570884
children 005633eed862
comparison
equal deleted inserted replaced
369:19cce6d2c470 370:b9c153e00e84
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 EasyMercurial
5
6 Based on HgExplorer by Jari Korhonen
7 Copyright (c) 2010 Jari Korhonen
8 Copyright (c) 2011 Chris Cannam
9 Copyright (c) 2011 Queen Mary, University of London
10
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2 of the
14 License, or (at your option) any later version. See the file
15 COPYING included with this distribution for more information.
16 */
17
18 #include "common.h"
19 #include "debug.h"
20
21 #include <QFileInfo>
22 #include <QProcessEnvironment>
23 #include <QStringList>
24 #include <QDir>
25 #include <QRegExp>
26
27 #include <sys/types.h>
28
29 #ifdef Q_OS_WIN32
30 #define _WIN32_WINNT 0x0500
31 #define SECURITY_WIN32
32 #include <windows.h>
33 #include <security.h>
34 #else
35 #include <errno.h>
36 #include <pwd.h>
37 #include <unistd.h>
38 #include <sys/ioctl.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <fcntl.h>
42 #include <signal.h>
43 #endif
44
45 QString findInPath(QString name, QString installPath, bool executableRequired)
46 {
47 bool found = false;
48 if (name != "") {
49 if (name[0] != '/'
50 #ifdef Q_OS_WIN32
51 && (QRegExp("^\\w:").indexIn(name) != 0)
52 #endif
53 ) {
54 #ifdef Q_OS_WIN32
55 QChar pathSep = ';';
56 #else
57 QChar pathSep = ':';
58 #endif
59 name = QFileInfo(name).fileName();
60 QString path =
61 QProcessEnvironment::systemEnvironment().value("PATH");
62 DEBUG << "findInPath: seeking location for binary " << name
63 << ": system path is " << path << endl;
64 if (installPath != "") {
65 DEBUG << "findInPath: install path is " << installPath
66 << ", adding to system path" << endl;
67 //!!! path = path + pathSep + installPath;
68 path = installPath + pathSep + path;
69 }
70 #ifndef Q_OS_WIN32
71 //!!!
72 path = path + ":/usr/local/bin";
73 DEBUG << "... adding /usr/local/bin just in case (fix and add settings dlg please)"
74 << endl;
75 #endif
76 QStringList elements = path.split(pathSep, QString::SkipEmptyParts);
77 foreach (QString element, elements) {
78 QString full = QDir(element).filePath(name);
79 QFileInfo fi(full);
80 DEBUG << "findInPath: looking at " << full << endl;
81 if (fi.exists() && fi.isFile()) {
82 DEBUG << "findInPath: it's a file" << endl;
83 if (!executableRequired || fi.isExecutable()) {
84 name = full;
85 DEBUG << "findInPath: found at " << name << endl;
86 found = true;
87 break;
88 }
89 }
90 }
91 } else {
92 // absolute path given
93 QFileInfo fi(name);
94 DEBUG << "findInPath: looking at absolute path " << name << endl;
95 if (fi.exists() && fi.isFile()) {
96 DEBUG << "findInPath: it's a file" << endl;
97 if (!executableRequired || fi.isExecutable()) {
98 DEBUG << "findInPath: found at " << name << endl;
99 found = true;
100 }
101 }
102 }
103 }
104 #ifdef Q_OS_WIN32
105 if (!found) {
106 if (!name.endsWith(".exe")) {
107 return findInPath(name + ".exe", installPath, executableRequired);
108 }
109 }
110 #endif
111 if (found) {
112 return name;
113 } else {
114 return "";
115 }
116 }
117
118 #ifdef Q_OS_WIN32
119 QString getUserRealName()
120 {
121 TCHAR buf[1024];
122 long unsigned int maxlen = 1000;
123 LPTSTR info = buf;
124
125 if (!GetUserNameEx(NameDisplay, info, &maxlen)) {
126 DEBUG << "GetUserNameEx failed: " << GetLastError() << endl;
127 return "";
128 }
129
130 #ifdef UNICODE
131 return QString::fromUtf16((const unsigned short *)info);
132 #else
133 return QString::fromLocal8Bit(info);
134 #endif
135 }
136 #else
137 #ifdef Q_OS_MAC
138 // Nothing here: definition is in common_osx.mm
139 #else
140 QString getUserRealName()
141 {
142 const int maxlen = 1023;
143 char buf[maxlen + 2];
144
145 if (getlogin_r(buf, maxlen)) return "";
146
147 struct passwd *p = getpwnam(buf);
148 if (!p) return "";
149
150 QString s(p->pw_gecos);
151 if (s != "") s = s.split(',')[0];
152 return s;
153 }
154 #endif
155 #endif
156
157 void loseControllingTerminal()
158 {
159 #ifndef Q_OS_WIN32
160
161 if (!isatty(0)) {
162 DEBUG << "stdin is not a terminal" << endl;
163 } else {
164 DEBUG << "stdin is a terminal, detaching from it" << endl;
165 if (ioctl(0, TIOCNOTTY, NULL) < 0) {
166 perror("ioctl failed");
167 DEBUG << "ioctl for TIOCNOTTY on stdin failed (errno = " << errno << ")" << endl;
168 } else {
169 DEBUG << "ioctl for TIOCNOTTY on stdin succeeded" << endl;
170 return;
171 }
172 }
173
174 int ttyfd = open("/dev/tty", O_RDWR);
175 if (ttyfd < 0) {
176 DEBUG << "failed to open controlling terminal" << endl;
177 } else {
178 if (ioctl(ttyfd, TIOCNOTTY, NULL) < 0) {
179 perror("ioctl failed");
180 DEBUG << "ioctl for TIOCNOTTY on controlling terminal failed (errno = " << errno << ")" << endl;
181 } else {
182 DEBUG << "ioctl for TIOCNOTTY on controlling terminal succeeded" << endl;
183 return;
184 }
185 }
186
187 #endif
188 }
189
190 void installSignalHandlers()
191 {
192 #ifndef Q_OS_WIN32
193 sigset_t sgnals;
194 sigemptyset (&sgnals);
195 sigaddset(&sgnals, SIGHUP);
196 sigaddset(&sgnals, SIGCONT);
197 pthread_sigmask(SIG_BLOCK, &sgnals, 0);
198 #endif
199 }
200
201 FolderStatus getFolderStatus(QString path)
202 {
203 if (path != "/" && path.endsWith("/")) {
204 path = path.left(path.length()-1);
205 }
206 DEBUG << "getFolderStatus: " << path << endl;
207 QFileInfo fi(path);
208 if (fi.exists()) {
209 DEBUG << "exists" << endl;
210 QDir dir(path);
211 if (!dir.exists()) { // returns false for files
212 DEBUG << "not directory" << endl;
213 return FolderIsFile;
214 }
215 if (QDir(dir.filePath(".hg")).exists()) {
216 DEBUG << "has repo" << endl;
217 return FolderHasRepo;
218 }
219 return FolderExists;
220 } else {
221 QDir parent = fi.dir();
222 if (parent.exists()) {
223 DEBUG << "parent exists" << endl;
224 return FolderParentExists;
225 }
226 return FolderUnknown;
227 }
228 }
229
230 QString getContainingRepoFolder(QString path)
231 {
232 if (getFolderStatus(path) == FolderHasRepo) return "";
233
234 QFileInfo me(path);
235 QFileInfo parent(me.dir().absolutePath());
236
237 while (me != parent) {
238 QString parentPath = parent.filePath();
239 if (getFolderStatus(parentPath) == FolderHasRepo) {
240 return parentPath;
241 }
242 me = parent;
243 parent = me.dir().absolutePath();
244 }
245
246 return "";
247 }
248
249 QString xmlEncode(QString s)
250 {
251 s
252 .replace("&", "&amp;")
253 .replace("<", "&lt;")
254 .replace(">", "&gt;")
255 .replace("\"", "&quot;")
256 .replace("'", "&apos;");
257
258 return s;
259 }