mirror of
https://github.com/ElvishArtisan/rivendell.git
synced 2025-04-07 01:13:50 +02:00
* Added an 'RDStringToHex()' function to 'lib/rd.conf.cpp'. * Fixed bugs in 'RDWaveFile' that caused strings of null characters to be written into unfilled CartChunk string fields.
1252 lines
23 KiB
C++
1252 lines
23 KiB
C++
// rdconf.cpp
|
|
//
|
|
// Small library for handling common configuration file tasks
|
|
//
|
|
// (C) Copyright 1996-2018 Fred Gleason <fredg@paravelsystems.com>
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU Library General Public License
|
|
// version 2 as published by the Free Software Foundation.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public
|
|
// License along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
//
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
|
|
#include <qdir.h>
|
|
#include <qhostaddress.h>
|
|
#include <qtextstream.h>
|
|
#include <qvariant.h>
|
|
#include <qmessagebox.h>
|
|
#include <qdir.h>
|
|
#define RDCONF_FILE_SEPARATOR '/'
|
|
#include <unistd.h>
|
|
#include <netdb.h>
|
|
#include <sys/timex.h>
|
|
#include <time.h>
|
|
|
|
#include "rddb.h"
|
|
#include "rdconf.h"
|
|
#include "rddatetime.h"
|
|
#include "rdescape_string.h"
|
|
|
|
#define BUFFER_SIZE 1024
|
|
|
|
int GetPrivateProfileBool(const char *sFilename,const char *cHeader,
|
|
const char *cLabel,bool bDefault=false)
|
|
{
|
|
char temp[255];
|
|
|
|
if(GetPrivateProfileString(sFilename,cHeader,cLabel,temp,"",254)<0) {
|
|
return bDefault;
|
|
}
|
|
if(temp[0]==0) {
|
|
return bDefault;
|
|
}
|
|
if((!strcasecmp(temp,"yes"))||(!strcasecmp(temp,"on"))) {
|
|
return true;
|
|
}
|
|
if((!strcasecmp(temp,"no"))||(!strcasecmp(temp,"off"))) {
|
|
return false;
|
|
}
|
|
return bDefault;
|
|
}
|
|
|
|
|
|
int GetPrivateProfileString(const char *sFilename,const char *cHeader,
|
|
const char *cLabel,char *cValue,
|
|
const char *cDefault,int dValueLength)
|
|
{
|
|
int i;
|
|
|
|
i=GetIni(sFilename,cHeader,cLabel,cValue,dValueLength);
|
|
if(i==0) {
|
|
return 0;
|
|
}
|
|
else {
|
|
strcpy(cValue,cDefault);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
int GetPrivateProfileInt(const char *sFilename,const char *cHeader,
|
|
const char *cLabel,int dDefault)
|
|
{
|
|
int c;
|
|
char sNum[12];
|
|
|
|
if(GetIni(sFilename,cHeader,cLabel,sNum,11)==0) {
|
|
if(sscanf(sNum,"%d",&c)==1) {
|
|
return c;
|
|
}
|
|
else {
|
|
return dDefault;
|
|
}
|
|
}
|
|
else {
|
|
return dDefault;
|
|
}
|
|
}
|
|
|
|
|
|
int GetPrivateProfileHex(const char *sFilename,const char *cHeader,
|
|
const char *cLabel,int dDefault)
|
|
{
|
|
char temp[256];
|
|
int n=dDefault;
|
|
|
|
GetPrivateProfileString(sFilename,cHeader,cLabel,temp,"",255);
|
|
sscanf(temp,"0x%x",&n);
|
|
return n;
|
|
}
|
|
|
|
|
|
double GetPrivateProfileDouble(const char *sFilename,const char *cHeader,
|
|
const char *cLabel,double dfDefault)
|
|
{
|
|
char temp[256];
|
|
double n=dfDefault;
|
|
|
|
GetPrivateProfileString(sFilename,cHeader,cLabel,temp,"",255);
|
|
sscanf(temp,"%lf",&n);
|
|
return n;
|
|
}
|
|
|
|
|
|
int GetIni(const char *sFileName,const char *cHeader,const char *cLabel,
|
|
char *cValue,int dValueLength)
|
|
/* get a value from the ini file */
|
|
|
|
{
|
|
FILE *cIniName;
|
|
char sName[BUFFER_SIZE];
|
|
char cIniBuffer[BUFFER_SIZE],cIniHeader[80],cIniLabel[80];
|
|
int i,j;
|
|
/* int iFileStat=NULL; */
|
|
int iFileStat;
|
|
|
|
strcpy(sName,sFileName);
|
|
cIniName=fopen(sName,"r");
|
|
if(cIniName==NULL) {
|
|
return 2; /* ini file doesn't exist! */
|
|
}
|
|
while(GetIniLine(cIniName,cIniBuffer)!=EOF) {
|
|
if(cIniBuffer[0]=='[') { /* start of section */
|
|
i=1;
|
|
while(cIniBuffer[i]!=']' && cIniBuffer!=0) {
|
|
cIniHeader[i-1]=cIniBuffer[i];
|
|
i++;
|
|
}
|
|
cIniHeader[i-1]=0;
|
|
if(strcmp(cIniHeader,cHeader)==0) { /* this is the right section! */
|
|
iFileStat=EOF+1; /* Make this anything other than EOF! */
|
|
while(iFileStat!=EOF) {
|
|
iFileStat=GetIniLine(cIniName,cIniBuffer);
|
|
if(cIniBuffer[0]=='[') return 1;
|
|
i=0;
|
|
while(cIniBuffer[i]!='=' && cIniBuffer[i]!=0) {
|
|
cIniLabel[i]=cIniBuffer[i];
|
|
i++;
|
|
}
|
|
cIniLabel[i++]=0;
|
|
if(strcmp(cIniLabel,cLabel)==0) { /* this is the right label! */
|
|
j=0;
|
|
while(j<dValueLength && cIniBuffer[i]!=0) {
|
|
cValue[j++]=cIniBuffer[i++];
|
|
}
|
|
cValue[j]=0;
|
|
fclose(cIniName);
|
|
return 0; /* value found! */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fclose(cIniName);
|
|
return 1; /* section or label not found! */
|
|
}
|
|
|
|
|
|
|
|
|
|
int GetIniLine(FILE *cIniName,char *cIniBuffer) /* read a line from the ini file */
|
|
|
|
{
|
|
int i;
|
|
|
|
for(i=0;i<BUFFER_SIZE-1;i++) {
|
|
cIniBuffer[i]=getc(cIniName);
|
|
switch(cIniBuffer[i]) {
|
|
|
|
case 10:
|
|
cIniBuffer[i]=0;
|
|
return 0;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
void Prepend(char *sPathname,char *sFilename)
|
|
{
|
|
char sTemp[256];
|
|
|
|
if(sPathname[strlen(sPathname)-1]!='/' && sFilename[0]!='/') {
|
|
strcat(sPathname,"/");
|
|
}
|
|
strcpy(sTemp,sPathname);
|
|
strcat(sTemp,sFilename);
|
|
strcpy(sFilename,sTemp);
|
|
}
|
|
|
|
|
|
int IncrementIndex(char *sPathname,int dMaxIndex)
|
|
{
|
|
int dLockname=-1;
|
|
FILE *hPathname;
|
|
int i;
|
|
char sLockname[256];
|
|
char sAccum[256];
|
|
int dIndex,dNewIndex;
|
|
|
|
/* Lock the index */
|
|
strcpy(sLockname,sPathname);
|
|
strcat(sLockname,".LCK");
|
|
i=0;
|
|
while(dLockname<0 && i<MAX_RETRIES) {
|
|
dLockname=open(sLockname,O_WRONLY|O_EXCL|O_CREAT,S_IRUSR|S_IWUSR);
|
|
i++;
|
|
}
|
|
if(dLockname<0) {
|
|
return -1;
|
|
}
|
|
sprintf(sAccum,"%d",getpid());
|
|
write(dLockname,sAccum,strlen(sAccum));
|
|
close(dLockname);
|
|
|
|
/* We've got the lock, so read the index */
|
|
hPathname=fopen(sPathname,"r");
|
|
if(hPathname==NULL) {
|
|
unlink(sLockname);
|
|
return -1;
|
|
}
|
|
if(fscanf(hPathname,"%d",&dIndex)!=1) {
|
|
fclose(hPathname);
|
|
unlink(sLockname);
|
|
return -1;
|
|
}
|
|
fclose(hPathname);
|
|
|
|
/* Update the index */
|
|
if((dIndex<dMaxIndex) || (dMaxIndex==0)) {
|
|
dNewIndex=dIndex+1;
|
|
}
|
|
else {
|
|
dNewIndex=1;
|
|
}
|
|
|
|
/* Write it back */
|
|
hPathname=fopen(sPathname,"w");
|
|
if(hPathname==NULL) {
|
|
unlink(sLockname);
|
|
return -1;
|
|
}
|
|
fprintf(hPathname,"%d",dNewIndex);
|
|
fclose(hPathname);
|
|
|
|
/* Release the lock */
|
|
unlink(sLockname);
|
|
|
|
/* Ensure a sane value to return and then exit */
|
|
if((dIndex>dMaxIndex)&&(dMaxIndex!=0)) {
|
|
dIndex=1;
|
|
}
|
|
|
|
return dIndex;
|
|
}
|
|
|
|
|
|
/*
|
|
* int StripLevel(char *sString)
|
|
*
|
|
* This strips the lower-most level from the pathname pointed to by 'sString'
|
|
*/
|
|
|
|
void StripLevel(char *sString)
|
|
{
|
|
int i; /* General Purpose Pointer */
|
|
int dString; /* Initial Length of 'sString' */
|
|
|
|
dString=strlen(sString)-1;
|
|
for(i=dString;i>=0;i--) {
|
|
if(sString[i]=='/') {
|
|
sString[i]=0;
|
|
return;
|
|
}
|
|
}
|
|
sString[0]=0;
|
|
}
|
|
|
|
|
|
|
|
|
|
bool GetLock(const char *sLockname)
|
|
{
|
|
int fd;
|
|
char sAccum[256];
|
|
|
|
if((fd=open(sLockname,O_WRONLY|O_EXCL|O_CREAT,S_IRUSR|S_IWUSR))<0) {
|
|
printf("failed!\n");
|
|
if(RDCheckPid(RDGetPathPart(sLockname),RDGetBasePart(sLockname))) {
|
|
return false;
|
|
}
|
|
ClearLock(sLockname);
|
|
if((fd=open(sLockname,O_WRONLY|O_EXCL|O_CREAT,S_IRUSR|S_IWUSR))<0) {
|
|
return false;
|
|
}
|
|
}
|
|
sprintf(sAccum,"%d",getpid());
|
|
write(fd,sAccum,strlen(sAccum));
|
|
close(fd);
|
|
return true;
|
|
}
|
|
|
|
|
|
void ClearLock(const char *sLockname)
|
|
{
|
|
unlink(sLockname);
|
|
}
|
|
|
|
|
|
QString RDGetPathPart(QString path)
|
|
{
|
|
int c;
|
|
|
|
// c=path.findRev('/');
|
|
c=path.findRev(RDCONF_FILE_SEPARATOR);
|
|
if(c<0) {
|
|
return QString("");
|
|
}
|
|
path.truncate(c+1);
|
|
return path;
|
|
}
|
|
|
|
|
|
QString RDGetBasePart(QString path)
|
|
{
|
|
int c;
|
|
|
|
// c=path.findRev('/');
|
|
c=path.findRev(RDCONF_FILE_SEPARATOR);
|
|
if(c<0) {
|
|
return path;
|
|
}
|
|
path.remove(0,c+1);
|
|
return path;
|
|
}
|
|
|
|
|
|
QString RDGetShortDate(QDate date)
|
|
{
|
|
return QString().sprintf("%02d/%02d/%04d",
|
|
date.month(),date.day(),date.year());
|
|
}
|
|
|
|
QString RDGetShortDayNameEN(int weekday)
|
|
{
|
|
QString day_name;
|
|
if ( weekday < 1 || weekday > 7 )
|
|
weekday = 1;
|
|
|
|
if (weekday == 1)
|
|
day_name = "Mon";
|
|
else if (weekday == 2)
|
|
day_name = "Tue";
|
|
else if (weekday == 3)
|
|
day_name = "Wed";
|
|
else if (weekday == 4)
|
|
day_name = "Thu";
|
|
else if (weekday == 5)
|
|
day_name = "Fri";
|
|
else if (weekday == 6)
|
|
day_name = "Sat";
|
|
else if (weekday == 7)
|
|
day_name = "Sun";
|
|
return day_name;
|
|
}
|
|
|
|
QFont::Weight RDGetFontWeight(QString string)
|
|
{
|
|
if(string.contains("Light",false)) {
|
|
return QFont::Light;
|
|
}
|
|
if(string.contains("Normal",false)) {
|
|
return QFont::Normal;
|
|
}
|
|
if(string.contains("DemiBold",false)) {
|
|
return QFont::DemiBold;
|
|
}
|
|
if(string.contains("Bold",false)) {
|
|
return QFont::Bold;
|
|
}
|
|
if(string.contains("Black",false)) {
|
|
return QFont::Black;
|
|
}
|
|
return QFont::Normal;
|
|
}
|
|
|
|
|
|
bool RDDetach(const QString &coredir)
|
|
{
|
|
if(!coredir.isEmpty()) {
|
|
chdir(coredir);
|
|
}
|
|
if(daemon(coredir.isEmpty(),0)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
bool RDBool(QString string)
|
|
{
|
|
if(string.contains("Y",false)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
QString RDYesNo(bool state)
|
|
{
|
|
if(state) {
|
|
return QString("Y");
|
|
}
|
|
return QString("N");
|
|
}
|
|
|
|
|
|
QHostAddress RDGetHostAddr()
|
|
{
|
|
FILE *file;
|
|
char host_name[256];
|
|
struct hostent *host_ent;
|
|
int host_address;
|
|
|
|
if((file=fopen("/etc/HOSTNAME","r"))==NULL) {
|
|
return QHostAddress();
|
|
}
|
|
if(fscanf(file,"%s",host_name)!=1) {
|
|
return QHostAddress();
|
|
}
|
|
if((host_ent=gethostbyname(host_name))==NULL) {
|
|
return QHostAddress();
|
|
}
|
|
host_address=16777216*(host_ent->h_addr_list[0][0]&0xff)+
|
|
65536*(host_ent->h_addr_list[0][1]&0xff)+
|
|
256*(host_ent->h_addr_list[0][2]&0xff)+
|
|
(host_ent->h_addr_list[0][3]&0xff);
|
|
return QHostAddress((Q_UINT32)host_address);
|
|
}
|
|
|
|
|
|
QString RDGetDisplay(bool strip_point)
|
|
{
|
|
QString display;
|
|
int l;
|
|
|
|
if(getenv("DISPLAY")[0]==':') {
|
|
display=RDGetHostAddr().toString()+QString(getenv("DISPLAY"));
|
|
}
|
|
else {
|
|
display=QString(getenv("DISPLAY"));
|
|
}
|
|
if(strip_point) {
|
|
l=display.length();
|
|
while(display.at(l)!=':') {
|
|
if(display.at(l--)=='.') {
|
|
return display.left(l+1);
|
|
}
|
|
}
|
|
}
|
|
return display;
|
|
}
|
|
|
|
|
|
bool RDDoesRowExist(const QString &table,const QString &name,
|
|
const QString &test,QSqlDatabase *db)
|
|
{
|
|
RDSqlQuery *q;
|
|
QString sql;
|
|
|
|
sql="select `"+name+"` from `"+table+"` where `"+name+"`="+
|
|
"\""+RDEscapeString(test)+"\"";
|
|
q=new RDSqlQuery(sql);
|
|
if(q->first()) {
|
|
delete q;
|
|
return true;
|
|
}
|
|
delete q;
|
|
return false;
|
|
}
|
|
|
|
|
|
bool RDDoesRowExist(const QString &table,const QString &name,unsigned test,
|
|
QSqlDatabase *db)
|
|
{
|
|
RDSqlQuery *q;
|
|
QString sql;
|
|
|
|
sql="select `"+name+"` from `"+table+"` where `"+name+"`="+
|
|
QString().sprintf("%d",test);
|
|
q=new RDSqlQuery(sql);
|
|
if(q->size()>0) {
|
|
delete q;
|
|
return true;
|
|
}
|
|
delete q;
|
|
return false;
|
|
}
|
|
|
|
|
|
QVariant RDGetSqlValue(const QString &table,const QString &name,
|
|
const QString &test,const QString ¶m,
|
|
bool *valid)
|
|
{
|
|
RDSqlQuery *q;
|
|
QString sql;
|
|
QVariant v;
|
|
|
|
sql="select `"+param+"` from `"+table+"` where `"+name+"`="+
|
|
"\""+RDEscapeString(test)+"\"";
|
|
q=new RDSqlQuery(sql);
|
|
if(q->isActive()) {
|
|
q->first();
|
|
v=q->value(0);
|
|
if(valid!=NULL) {
|
|
*valid=!q->isNull(0);
|
|
}
|
|
delete q;
|
|
return v;
|
|
}
|
|
delete q;
|
|
return QVariant();
|
|
}
|
|
|
|
|
|
bool RDIsSqlNull(const QString &table,const QString &name,const QString &test,
|
|
const QString ¶m,QSqlDatabase *db)
|
|
{
|
|
RDSqlQuery *q;
|
|
QString sql;
|
|
|
|
sql="select `"+param+"` from `"+table+"` where `"+name+"`="+
|
|
"\""+RDEscapeString(test)+"\"";
|
|
q=new RDSqlQuery(sql);
|
|
if(q->isActive()) {
|
|
q->first();
|
|
if(q->isNull(0)) {
|
|
delete q;
|
|
return true;
|
|
}
|
|
else {
|
|
delete q;
|
|
return false;
|
|
}
|
|
}
|
|
delete q;
|
|
return true;
|
|
}
|
|
|
|
|
|
bool RDIsSqlNull(const QString &table,const QString &name,unsigned test,
|
|
const QString ¶m,QSqlDatabase *db)
|
|
{
|
|
RDSqlQuery *q;
|
|
QString sql;
|
|
|
|
sql="select `"+param+"` from `"+table+"` where `"+name+"`="+
|
|
QString().sprintf("%d",test);
|
|
q=new RDSqlQuery(sql);
|
|
if(q->isActive()) {
|
|
q->first();
|
|
if(q->isNull(0)) {
|
|
delete q;
|
|
return true;
|
|
}
|
|
else {
|
|
delete q;
|
|
return false;
|
|
}
|
|
}
|
|
delete q;
|
|
return true;
|
|
}
|
|
|
|
|
|
QVariant RDGetSqlValue(const QString &table,const QString &name,unsigned test,
|
|
const QString ¶m,bool *valid)
|
|
{
|
|
RDSqlQuery *q;
|
|
QString sql;
|
|
QVariant v;
|
|
|
|
sql="select `"+param+"` from `"+table+"` where `"+name+"`="+
|
|
QString().sprintf("%u",test);
|
|
q=new RDSqlQuery(sql);
|
|
if(q->first()) {
|
|
v=q->value(0);
|
|
if(valid!=NULL) {
|
|
*valid=!q->isNull(0);
|
|
}
|
|
delete q;
|
|
return v;
|
|
}
|
|
delete q;
|
|
return QVariant();
|
|
}
|
|
|
|
|
|
QString RDGetTimeLength(int mseconds,bool leadzero,bool tenths)
|
|
{
|
|
int hour,min,seconds,tenthsecs;
|
|
char negative[2];
|
|
|
|
if(mseconds<0) {
|
|
mseconds=-mseconds;
|
|
strcpy(negative,"-");
|
|
}
|
|
else {
|
|
negative[0]=0;
|
|
}
|
|
QTime time_length(QTime(0,0,0).addMSecs(mseconds));
|
|
hour = time_length.hour();
|
|
min = time_length.minute();
|
|
seconds = time_length.second();
|
|
mseconds = time_length.msec();
|
|
tenthsecs=mseconds/100;
|
|
if(leadzero) {
|
|
if(tenths) {
|
|
return QString(negative)+
|
|
QString().sprintf("%d:%02d:%02d.%d",hour,min,seconds,tenthsecs);
|
|
}
|
|
return QString(negative)+
|
|
QString().sprintf("%d:%02d:%02d",hour,min,seconds);
|
|
}
|
|
if((hour==0)&&(min==0)) {
|
|
if(tenths) {
|
|
return QString(negative)+QString().sprintf(":%02d.%d",seconds,tenthsecs);
|
|
}
|
|
return QString(negative)+QString().sprintf(":%02d",seconds);
|
|
}
|
|
if(hour==0) {
|
|
if(tenths) {
|
|
return QString(negative)+
|
|
QString().sprintf("%2d:%02d.%d",min,seconds,tenthsecs);
|
|
}
|
|
return QString(negative)+QString().sprintf("%2d:%02d",min,seconds);
|
|
}
|
|
if(tenths) {
|
|
return QString(negative)+
|
|
QString().sprintf("%2d:%02d:%02d.%d",hour,min,seconds,tenthsecs);
|
|
}
|
|
return QString(negative)+QString().sprintf("%2d:%02d:%02d",hour,min,seconds);
|
|
}
|
|
|
|
|
|
int RDSetTimeLength(const QString &str)
|
|
{
|
|
int istate=2;
|
|
QString field;
|
|
int res=0;
|
|
|
|
if(str.isEmpty()) {
|
|
return -1;
|
|
}
|
|
for(int i=0;i<str.length();i++) {
|
|
if(str.at(i)==':') {
|
|
istate--;
|
|
}
|
|
}
|
|
if(istate<0) {
|
|
return -1;
|
|
}
|
|
for(int i=0;i<str.length();i++) {
|
|
if(str.at(i).isNumber()) {
|
|
field+=str.at(i);
|
|
}
|
|
else {
|
|
if((str.at(i)==':')||(str.at(i)=='.')) {
|
|
if(field.length()>2) {
|
|
return -1;
|
|
}
|
|
switch(istate) {
|
|
case 0:
|
|
res+=3600000*field.toInt();
|
|
break;
|
|
|
|
case 1:
|
|
res+=60000*field.toInt();
|
|
break;
|
|
|
|
case 2:
|
|
res+=1000*field.toInt();
|
|
break;
|
|
}
|
|
istate++;
|
|
field="";
|
|
}
|
|
else {
|
|
if(!str.at(i).isSpace()) {
|
|
return -2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
switch(istate) {
|
|
case 2:
|
|
res+=1000*field.toInt();
|
|
break;
|
|
|
|
case 3:
|
|
switch(field.length()) {
|
|
case 1:
|
|
res+=100*field.toInt();
|
|
break;
|
|
|
|
case 2:
|
|
res+=10*field.toInt();
|
|
break;
|
|
|
|
case 3:
|
|
res+=field.toInt();
|
|
break;
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/*
|
|
bool RDCopy(const QString &srcfile,const QString &destfile)
|
|
{
|
|
int src_fd;
|
|
int dest_fd;
|
|
struct stat src_stat;
|
|
struct stat dest_stat;
|
|
char *buf=NULL;
|
|
int n;
|
|
|
|
if((src_fd=open((const char *)srcfile,O_RDONLY))<0) {
|
|
return false;
|
|
}
|
|
if(fstat(src_fd,&src_stat)<0) {
|
|
close(src_fd);
|
|
return false;
|
|
}
|
|
if((dest_fd=open((const char *)destfile,O_RDWR|O_CREAT,src_stat.st_mode))
|
|
<0) {
|
|
close(src_fd);
|
|
return false;
|
|
}
|
|
if(fstat(dest_fd,&dest_stat)<0) {
|
|
close(src_fd);
|
|
close(dest_fd);
|
|
return false;
|
|
}
|
|
buf=(char *)malloc(dest_stat.st_blksize);
|
|
while((n=read(src_fd,buf,dest_stat.st_blksize))==dest_stat.st_blksize) {
|
|
write(dest_fd,buf,dest_stat.st_blksize);
|
|
}
|
|
write(dest_fd,buf,n);
|
|
free(buf);
|
|
close(src_fd);
|
|
close(dest_fd);
|
|
return true;
|
|
}
|
|
*/
|
|
|
|
bool RDCopy(const QString &srcfile,const QString &destfile)
|
|
{
|
|
int src_fd;
|
|
int dest_fd;
|
|
|
|
if((src_fd=open((const char *)srcfile,O_RDONLY))<0) {
|
|
return false;
|
|
}
|
|
if((dest_fd=open((const char *)destfile,O_WRONLY|O_CREAT,S_IWUSR))<0) {
|
|
close(src_fd);
|
|
return false;
|
|
}
|
|
bool ret=RDCopy(src_fd,dest_fd);
|
|
close(src_fd);
|
|
close(dest_fd);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
bool RDCopy(const QString &srcfile,int dest_fd)
|
|
{
|
|
int src_fd;
|
|
|
|
if((src_fd=open((const char *)srcfile,O_RDONLY))<0) {
|
|
return false;
|
|
}
|
|
bool ret=RDCopy(src_fd,dest_fd);
|
|
close(src_fd);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
bool RDCopy(int src_fd,const QString &destfile)
|
|
{
|
|
int dest_fd;
|
|
|
|
if((dest_fd=open((const char *)destfile,O_WRONLY|O_CREAT,S_IWUSR))<0) {
|
|
return false;
|
|
}
|
|
bool ret=RDCopy(src_fd,dest_fd);
|
|
close(dest_fd);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
bool RDCopy(int src_fd,int dest_fd)
|
|
{
|
|
struct stat src_stat;
|
|
struct stat dest_stat;
|
|
char *buf=NULL;
|
|
int n;
|
|
|
|
if(fstat(src_fd,&src_stat)<0) {
|
|
return false;
|
|
}
|
|
if(fstat(dest_fd,&dest_stat)<0) {
|
|
return false;
|
|
}
|
|
if(fchmod(dest_fd,src_stat.st_mode)<0) {
|
|
return false;
|
|
}
|
|
buf=(char *)malloc(dest_stat.st_blksize);
|
|
while((n=read(src_fd,buf,dest_stat.st_blksize))==dest_stat.st_blksize) {
|
|
write(dest_fd,buf,dest_stat.st_blksize);
|
|
}
|
|
write(dest_fd,buf,n);
|
|
free(buf);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool RDWritePid(const QString &dirname,const QString &filename,int owner,
|
|
int group)
|
|
{
|
|
FILE *file;
|
|
mode_t prev_mask;
|
|
QString pathname=dirname+"/"+filename;
|
|
|
|
prev_mask = umask(0113); // Set umask so pid files are user and group writable.
|
|
file=fopen((const char *)pathname,"w");
|
|
umask(prev_mask);
|
|
if(file==NULL) {
|
|
return false;
|
|
}
|
|
fprintf(file,"%d",getpid());
|
|
fclose(file);
|
|
chown((const char *)pathname,owner,group);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void RDDeletePid(const QString &dirname,const QString &filename)
|
|
{
|
|
QString pid=dirname+"/"+filename;
|
|
unlink((const char *)pid);
|
|
}
|
|
|
|
|
|
bool RDCheckPid(const QString &dirname,const QString &filename)
|
|
{
|
|
QDir dir;
|
|
QString path;
|
|
path=QString("/proc/")+
|
|
QString().sprintf("%d",RDGetPid(dirname+QString("/")+filename));
|
|
dir.setPath(path);
|
|
return dir.exists();
|
|
}
|
|
|
|
|
|
pid_t RDGetPid(const QString &pidfile)
|
|
{
|
|
FILE *handle;
|
|
pid_t ret;
|
|
|
|
if((handle=fopen((const char *)pidfile,"r"))==NULL) {
|
|
return -1;
|
|
}
|
|
if(fscanf(handle,"%d",&ret)!=1) {
|
|
ret=-1;
|
|
}
|
|
fclose(handle);
|
|
return ret;
|
|
}
|
|
|
|
|
|
bool RDTimeSynced()
|
|
{
|
|
struct timex timex;
|
|
|
|
memset(&timex,0,sizeof(struct timex));
|
|
if(adjtimex(&timex)==TIME_OK) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
QString RDGetHomeDir(bool *found)
|
|
{
|
|
if(getenv("HOME")==NULL) {
|
|
if(found!=NULL) {
|
|
*found=false;
|
|
}
|
|
return QString("/");
|
|
}
|
|
if(found!=NULL) {
|
|
*found=true;
|
|
}
|
|
return QString(getenv("HOME"));
|
|
}
|
|
|
|
|
|
QString RDTruncateAfterWord(QString str,int word,bool add_dots)
|
|
{
|
|
QString simple=str.simplifyWhiteSpace();
|
|
int quan=0;
|
|
int point;
|
|
|
|
for(int i=0;i<simple.length();i++) {
|
|
if(simple.at(i).isSpace()) {
|
|
quan++;
|
|
point=i;
|
|
if(quan==word) {
|
|
if(add_dots) {
|
|
return simple.left(point)+QString("...");
|
|
}
|
|
else {
|
|
return simple.left(point);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return simple;
|
|
}
|
|
|
|
|
|
QString RDHomeDir()
|
|
{
|
|
if(getenv("HOME")==NULL) {
|
|
return QString("/");
|
|
}
|
|
return QString(getenv("HOME"));
|
|
}
|
|
|
|
|
|
QString RDTempDir()
|
|
{
|
|
char path[PATH_MAX]="/tmp/rddbmgrXXXXXX";
|
|
|
|
return QString(mkdtemp(path));
|
|
}
|
|
|
|
|
|
QString RDTempFile()
|
|
{
|
|
int fd=-1;
|
|
char dirname[PATH_MAX];
|
|
strncpy(dirname,"/tmp/rivendellXXXXXX",PATH_MAX);
|
|
if((fd=mkstemp(dirname))>0) {
|
|
close(fd);
|
|
return QString(dirname);
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
|
|
QString RDTimeZoneName(const QDateTime &datetime)
|
|
{
|
|
char name[20];
|
|
time_t time=datetime.toTime_t();
|
|
strftime(name,20,"%Z",localtime(&time));
|
|
return QString(name);
|
|
}
|
|
|
|
|
|
QString RDDowCode(int dow)
|
|
{
|
|
QString ret;
|
|
switch(dow) {
|
|
case 1:
|
|
ret=QString("MON");
|
|
break;
|
|
|
|
case 2:
|
|
ret=QString("TUE");
|
|
break;
|
|
|
|
case 3:
|
|
ret=QString("WED");
|
|
break;
|
|
|
|
case 4:
|
|
ret=QString("THU");
|
|
break;
|
|
|
|
case 5:
|
|
ret=QString("FRI");
|
|
break;
|
|
|
|
case 6:
|
|
ret=QString("SAT");
|
|
break;
|
|
|
|
case 7:
|
|
ret=QString("SUN");
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
QDateTime RDLocalToUtc(const QDateTime &localdatetime)
|
|
{
|
|
return localdatetime.addSecs(RDTimeZoneOffset());
|
|
}
|
|
|
|
|
|
QTime RDLocalToUtc(const QTime &localtime)
|
|
{
|
|
return localtime.addSecs(RDTimeZoneOffset());
|
|
}
|
|
|
|
|
|
QDateTime RDUtcToLocal(const QDateTime &gmtdatetime)
|
|
{
|
|
return gmtdatetime.addSecs(-RDTimeZoneOffset());
|
|
}
|
|
|
|
|
|
QTime RDUtcToLocal(const QTime &gmttime)
|
|
{
|
|
return gmttime.addSecs(-RDTimeZoneOffset());
|
|
}
|
|
|
|
/*
|
|
int RDTimeZoneOffset()
|
|
{
|
|
time_t t=time(&t);
|
|
struct tm *tm=localtime(&t);
|
|
time_t local_time=3600*tm->tm_hour+60*tm->tm_min+tm->tm_sec;
|
|
tm=gmtime(&t);
|
|
time_t gmt_time=3600*tm->tm_hour+60*tm->tm_min+tm->tm_sec;
|
|
|
|
int offset=gmt_time-local_time;
|
|
if(offset>43200) {
|
|
offset=offset-86400;
|
|
}
|
|
if(offset<-43200) {
|
|
offset=offset+86400;
|
|
}
|
|
|
|
return offset;
|
|
}
|
|
*/
|
|
|
|
QColor RDGetTextColor(const QColor &background_color)
|
|
{
|
|
int h,s,v;
|
|
QColor color=background_color;
|
|
|
|
background_color.getHsv(&h,&s,&v);
|
|
if(v<128) {
|
|
color=Qt::white;
|
|
}
|
|
else {
|
|
if((h>210)&&(h<270)&&(s>128)) { // Special case for blue
|
|
color=Qt::white;
|
|
}
|
|
else {
|
|
color=Qt::black;
|
|
}
|
|
}
|
|
|
|
return color;
|
|
}
|
|
|
|
|
|
bool RDProcessActive(const QString &cmd)
|
|
{
|
|
QStringList cmds;
|
|
|
|
cmds.push_back(cmd);
|
|
return RDProcessActive(cmds);
|
|
}
|
|
|
|
|
|
bool RDProcessActive(const QStringList &cmds)
|
|
{
|
|
QStringList dirs;
|
|
QDir *proc_dir=new QDir("/proc");
|
|
bool ok=false;
|
|
FILE *f=NULL;
|
|
char line[1024];
|
|
QString cmdline;
|
|
|
|
proc_dir->setFilter(QDir::Dirs);
|
|
dirs=proc_dir->entryList();
|
|
for(int i=0;i<dirs.size();i++) {
|
|
dirs[i].toInt(&ok);
|
|
if(ok) {
|
|
if((f=fopen(QString("/proc/")+dirs[i]+"/cmdline","r"))!=NULL) {
|
|
if(fgets(line,1024,f)!=NULL) {
|
|
QStringList f1=QString(line).split(" ",QString::SkipEmptyParts);
|
|
QStringList f2=f1[0].split("/",QString::SkipEmptyParts);
|
|
cmdline=f2[f2.size()-1];
|
|
for(int j=0;j<cmds.size();j++) {
|
|
if(cmdline==cmds[j]) {
|
|
fclose(f);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
fclose(f);
|
|
}
|
|
}
|
|
}
|
|
|
|
delete proc_dir;
|
|
return false;
|
|
}
|
|
|
|
|
|
bool RDModulesActive()
|
|
{
|
|
QStringList cmds;
|
|
|
|
cmds.push_back("rdadmin");
|
|
cmds.push_back("rdairplay");
|
|
cmds.push_back("rdcastmanager");
|
|
cmds.push_back("rdcatch");
|
|
cmds.push_back("rdlibrary");
|
|
cmds.push_back("rdlogedit");
|
|
cmds.push_back("rdlogin");
|
|
cmds.push_back("rdlogmanager");
|
|
cmds.push_back("rdpanel");
|
|
cmds.push_back("rddbcheck");
|
|
cmds.push_back("rdgpimon");
|
|
return RDProcessActive(cmds);
|
|
}
|
|
|
|
|
|
QByteArray RDStringToData(const QString &str)
|
|
{
|
|
int istate=0;
|
|
unsigned n;
|
|
QString code;
|
|
QByteArray ret;
|
|
bool ok=false;
|
|
|
|
for(int i=0;i<str.length();i++) {
|
|
switch(istate) {
|
|
case 0:
|
|
if(str.at(i)==QChar('%')) {
|
|
istate=1;
|
|
}
|
|
else {
|
|
ret+=str.at(i);
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
n=str.mid(i,1).toUInt(&ok);
|
|
if((!ok)||(n>9)) {
|
|
istate=0;
|
|
}
|
|
code=str.mid(i,1);
|
|
istate=2;
|
|
break;
|
|
|
|
case 2:
|
|
n=str.mid(i,1).toUInt(&ok);
|
|
if((!ok)||(n>9)) {
|
|
istate=0;
|
|
}
|
|
code+=str.mid(i,1);
|
|
ret+=code.toUInt(NULL,16);
|
|
istate=0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
QString RDStringToHex(const QString &str)
|
|
{
|
|
QByteArray bytes=str.toUtf8();
|
|
QString ret="";
|
|
|
|
for(int i=0;i<bytes.length();i++) {
|
|
ret+=QString().sprintf("%02X ",0xFF&bytes[i]);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
QList<pid_t> RDGetPids(const QString &program)
|
|
{
|
|
QList<pid_t> pids;
|
|
bool ok=false;
|
|
|
|
QDir procdir("/proc");
|
|
QStringList files=
|
|
procdir.entryList(QDir::Dirs|QDir::NoDotAndDotDot,QDir::Name);
|
|
|
|
for(int i=0;i<files.size();i++) {
|
|
pid_t pid=files.at(i).toInt(&ok);
|
|
if(ok) {
|
|
QFile file(QString("/proc/")+files.at(i)+"/cmdline");
|
|
if(file.open(QIODevice::ReadOnly)) {
|
|
QTextStream strm(&file);
|
|
strm.setCodec("UTF-8");
|
|
QStringList f0=strm.readLine().split(" ");
|
|
QStringList f1=f0.at(0).split("/");
|
|
if(f1.back().left(f1.back().length()-1)==program.trimmed()) {
|
|
pids.push_back(pid);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return pids;
|
|
}
|