Mercurial > hg > easyhg
view src/common.cpp @ 676:cb4f7c3c01dd
Toward some CI bits
author | Chris Cannam |
---|---|
date | Thu, 06 Dec 2018 13:45:23 +0000 |
parents | f9b805d8cab4 |
children | c0b46d0514a7 |
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ /* EasyMercurial Based on HgExplorer by Jari Korhonen Copyright (c) 2010 Jari Korhonen Copyright (c) 2013 Chris Cannam Copyright (c) 2013 Queen Mary, University of London This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See the file COPYING included with this distribution for more information. */ #include "common.h" #include "debug.h" #include <QFileInfo> #include <QProcessEnvironment> #include <QStringList> #include <QDir> #include <QRegExp> #include <sys/types.h> #ifdef Q_OS_WIN32 #define _WIN32_WINNT 0x0500 #define SECURITY_WIN32 #include <windows.h> #include <security.h> #include <process.h> #else #include <errno.h> #include <pwd.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <signal.h> #include <stdio.h> #endif QString findInPath(QString name, QString installPath, bool executableRequired) { bool found = false; if (name != "") { if (name[0] != '/' #ifdef Q_OS_WIN32 && (QRegExp("^\\w:").indexIn(name) != 0) #endif ) { #ifdef Q_OS_WIN32 QChar pathSep = ';'; #else QChar pathSep = ':'; #endif name = QFileInfo(name).fileName(); QString path = QProcessEnvironment::systemEnvironment().value("PATH"); DEBUG << "findInPath: seeking location for binary " << name << ": system path is " << path << endl; if (installPath != "") { DEBUG << "findInPath: install path is " << installPath << ", adding to system path" << endl; //!!! path = path + pathSep + installPath; path = installPath + pathSep + path; } #ifndef Q_OS_WIN32 //!!! path = path + ":/usr/local/bin"; DEBUG << "... adding /usr/local/bin just in case (fix and add settings dlg please)" << endl; #endif QStringList elements = path.split(pathSep, QString::SkipEmptyParts); foreach (QString element, elements) { QString full = QDir(element).filePath(name); QFileInfo fi(full); DEBUG << "findInPath: looking at " << full << endl; if (fi.exists() && fi.isFile()) { DEBUG << "findInPath: it's a file" << endl; if (!executableRequired || fi.isExecutable()) { name = full; DEBUG << "findInPath: found at " << name << endl; found = true; break; } } } } else { // absolute path given QFileInfo fi(name); DEBUG << "findInPath: looking at absolute path " << name << endl; if (fi.exists() && fi.isFile()) { DEBUG << "findInPath: it's a file" << endl; if (!executableRequired || fi.isExecutable()) { DEBUG << "findInPath: found at " << name << endl; found = true; } } } } #ifdef Q_OS_WIN32 if (!found) { if (!name.endsWith(".exe")) { return findInPath(name + ".exe", installPath, executableRequired); } } #endif if (found) { return name; } else { return ""; } } #ifdef Q_OS_WIN32 QString getUserRealName() { TCHAR buf[1024]; long unsigned int maxlen = 1000; LPTSTR info = buf; if (!GetUserNameEx(NameDisplay, info, &maxlen)) { DEBUG << "GetUserNameEx failed: " << GetLastError() << endl; return ""; } #ifdef UNICODE return QString::fromUtf16((const unsigned short *)info); #else return QString::fromLocal8Bit(info); #endif } #else #ifdef Q_OS_MAC // Nothing here: definition is in common_osx.mm #else QString getUserRealName() { const int maxlen = 1023; char buf[maxlen + 2]; if (getlogin_r(buf, maxlen)) return ""; struct passwd *p = getpwnam(buf); if (!p) return ""; QString s(p->pw_gecos); if (s != "") s = s.split(',')[0]; return s; } #endif #endif void loseControllingTerminal() { #ifndef Q_OS_WIN32 if (!isatty(0)) { DEBUG << "stdin is not a terminal" << endl; } else { DEBUG << "stdin is a terminal, detaching from it" << endl; if (ioctl(0, TIOCNOTTY, NULL) < 0) { perror("ioctl failed"); DEBUG << "ioctl for TIOCNOTTY on stdin failed (errno = " << errno << ")" << endl; } else { DEBUG << "ioctl for TIOCNOTTY on stdin succeeded" << endl; return; } } int ttyfd = open("/dev/tty", O_RDWR); if (ttyfd < 0) { DEBUG << "failed to open controlling terminal" << endl; } else { if (ioctl(ttyfd, TIOCNOTTY, NULL) < 0) { perror("ioctl failed"); DEBUG << "ioctl for TIOCNOTTY on controlling terminal failed (errno = " << errno << ")" << endl; } else { DEBUG << "ioctl for TIOCNOTTY on controlling terminal succeeded" << endl; return; } } #endif } void installSignalHandlers() { #ifndef Q_OS_WIN32 sigset_t sgnals; sigemptyset (&sgnals); sigaddset(&sgnals, SIGHUP); sigaddset(&sgnals, SIGCONT); pthread_sigmask(SIG_BLOCK, &sgnals, 0); #endif } ProcessStatus GetProcessStatus(int pid) { #ifdef _WIN32 HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if (!handle) { return ProcessNotRunning; } else { CloseHandle(handle); return ProcessRunning; } #else if (kill(getpid(), 0) == 0) { if (kill(pid, 0) == 0) { return ProcessRunning; } else { return ProcessNotRunning; } } else { return UnknownProcessStatus; } #endif } FolderStatus getFolderStatus(QString path) { if (path != "/" && path.endsWith("/")) { path = path.left(path.length()-1); } DEBUG << "getFolderStatus: " << path << endl; QFileInfo fi(path); if (fi.exists()) { DEBUG << "exists" << endl; QDir dir(path); if (!dir.exists()) { // returns false for files DEBUG << "not directory" << endl; return FolderIsFile; } if (QDir(dir.filePath(".hg")).exists()) { DEBUG << "has repo" << endl; return FolderHasRepo; } return FolderExists; } else { QDir parent = fi.dir(); if (parent.exists()) { DEBUG << "parent exists" << endl; return FolderParentExists; } return FolderUnknown; } } QString getContainingRepoFolder(QString path) { if (getFolderStatus(path) == FolderHasRepo) return ""; QFileInfo me(path); QFileInfo parent(me.dir().absolutePath()); while (me != parent) { QString parentPath = parent.filePath(); if (getFolderStatus(parentPath) == FolderHasRepo) { return parentPath; } me = parent; parent = me.dir().absolutePath(); } return ""; } QString xmlEncode(QString s) { s .replace("&", "&") .replace("<", "<") .replace(">", ">") .replace("\"", """) .replace("'", "'"); return s; } QString uniDecode(QString s) { QString d; for (int i = 0; i < s.length(); ++i) { // backslash escaped with another backslash: replace with a // single backslash and skip on if (i+1 < s.length() && s[i] == '\\' && s[i+1] == '\\') { d += '\\'; i += 1; continue; } // unescaped backslash followed by u and at least four more // chars: replace with Unicode character if (i+5 < s.length() && s[i] == '\\' && s[i+1] == 'u') { QString uni = s.mid(i+2, 4); QByteArray ba = QByteArray::fromHex(uni.toLatin1()); d += QChar(ba[1], ba[0]); i += 5; continue; } // default case: leave alone d += s[i]; } return d; } QByteArray randomKey() { static int len = 16; QByteArray ba; ba.resize(len); char *buffer = ba.data(); #ifdef Q_OS_WIN32 HCRYPTPROV provider = 0; if (!CryptAcquireContextW(&provider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { return QByteArray(); } if (!CryptGenRandom(provider, len, (BYTE *)buffer)) { CryptReleaseContext(provider, 0); return QByteArray(); } CryptReleaseContext(provider, 0); #else FILE *rf = fopen("/dev/urandom", "r"); if (!rf) { return QByteArray(); } for (int i = 0; i < len; ++i) { buffer[i] = fgetc(rf); } fclose(rf); #endif return ba; }