void cPicturePlayer::SetPicture(const char *FileName) { int f = open(FileName, O_RDONLY); if (f >= 0) { for (;;) { length = read(f, buffer, size); if (length > 0) { if (length >= size) { int NewSize = size * 3 / 2; if (uchar *NewBuffer = (uchar *)realloc(buffer, NewSize)) { buffer = NewBuffer; size = NewSize; } else { LOG_ERROR_STR("out of memory"); break; } lseek(f, 0, SEEK_SET); continue; } DeviceStillPicture(buffer, length); } else LOG_ERROR_STR(FileName); break; } close(f); } else LOG_ERROR_STR(FileName); }
void cFileWriter::Action(void) { time_t t = time(NULL); unsigned int skipped = 0; while (Running()) { int Count; uchar *p = remux->Get(Count, &pictureType, 1); while(skipped < 10 && (remux->SFmode() == SF_UNKNOWN || remux->TSmode() == rAuto)){ // TB: give remuxer a chance to detect the stream type skipped++; Count = 0; continue; } if (p && Count) { // esyslog("COUNT %i\n", Count); if (!Running() && pictureType == I_FRAME) // finish the recording before the next 'I' frame break; if (NextFile()) { #if 1 // Add PAT+PMT at every filestart and every MB if ((!fileSize || diffSize > PATPMT_DISTANCE) && remux->TSmode()==SF_H264) { uchar patpmt[2*188]; int plen; plen=remux->GetPATPMT(patpmt, 2*188); if (plen) { if (recordFile->Write(patpmt, plen) < 0) { LOG_ERROR_STR(fileName->Name()); break; } fileSize+=plen; } diffSize=0; } #endif if (index && pictureType != NO_PICTURE) index->Write(pictureType, fileName->Number(), fileSize); if (recordFile->Write(p, Count) < 0) { LOG_ERROR_STR(fileName->Name()); break; } fileSize += Count; diffSize += Count; remux->Del(Count); } else break; t = time(NULL); } else if (time(NULL) - t > MAXBROKENTIMEOUT) { esyslog("ERROR: video data stream broken"); //cThread::EmergencyExit(true); Skins.Message(mtError, tr("can't record - check your configuration")); t = time(NULL); } } }
bool cLircRemote::Connect(void) { if ((f = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0) { if (connect(f, (struct sockaddr *)&addr, sizeof(addr)) >= 0) return true; LOG_ERROR_STR(addr.sun_path); close(f); f = -1; } else LOG_ERROR_STR(addr.sun_path); return false; }
bool cDvbDevice::Probe(const char *FileName) { if (access(FileName, F_OK) == 0) { dsyslog("probing %s", FileName); int f = open(FileName, O_RDONLY); if (f >= 0) { close(f); return true; } else if (errno != ENODEV && errno != EINVAL) LOG_ERROR_STR(FileName); } else if (errno != ENOENT) LOG_ERROR_STR(FileName); return false; }
bool ManagerConnection::login(const std::string& eventMask) { if (!this->isConnected()) { LOG_ERROR_STR("Must connect before Login!!"); return (false); } else if (this->isAuthenticated()) { LOG_ERROR_STR("Already Logged in!!"); return (false); } if (this->getUsername().empty() || this->getPassword().empty()) { LOG_ERROR_STR("Must Provide UserName as Password!!"); return (false); } LoginAction* la = NULL; ChallengeAction challengeAction("MD5"); ChallengeResponse* carp = (ChallengeResponse*) this->syncSendAction(challengeAction); if (carp->isTypeSuccess()) { std::string challenge(carp->getChallenge()); if (!challenge.empty()) { MD5 md5; md5.update(challenge.c_str(), challenge.length()); md5.update(this->getPassword().c_str(), this->getPassword().length()); md5.finalize(); la = new LoginAction(this->getUsername(), "MD5", md5.hexdigest()); } } delete (carp); if (!la) { la = new LoginAction(this->getUsername(), this->getPassword()); } if (!eventMask.empty()) { la->setEvents(eventMask); } ManagerResponse *mr = this->syncSendAction(*la); bool rt(mr->isTypeSuccess()); if (rt) { this->setState(AUTHENTICATED); } delete (la); delete (mr); return (rt); }
void cRecorder::Action(void) { cTimeMs t(MAXBROKENTIMEOUT); bool InfoWritten = false; bool FirstIframeSeen = false; while (Running()) { int r; uchar *b = ringBuffer->Get(r); if (b) { int Count = frameDetector->Analyze(b, r); if (Count) { if (!Running() && frameDetector->IndependentFrame()) // finish the recording before the next independent frame break; if (frameDetector->Synced()) { if (!InfoWritten) { cRecordingInfo RecordingInfo(recordingName); if (RecordingInfo.Read()) { if (frameDetector->FramesPerSecond() > 0 && DoubleEqual(RecordingInfo.FramesPerSecond(), DEFAULTFRAMESPERSECOND) && !DoubleEqual(RecordingInfo.FramesPerSecond(), frameDetector->FramesPerSecond())) { RecordingInfo.SetFramesPerSecond(frameDetector->FramesPerSecond()); RecordingInfo.Write(); Recordings.UpdateByName(recordingName); } } InfoWritten = true; cRecordingUserCommand::InvokeCommand(RUC_STARTRECORDING, recordingName); } if (FirstIframeSeen || frameDetector->IndependentFrame()) { FirstIframeSeen = true; // start recording with the first I-frame if (!NextFile()) break; if (index && frameDetector->NewFrame()) index->Write(frameDetector->IndependentFrame(), fileName->Number(), fileSize); if (frameDetector->IndependentFrame()) { recordFile->Write(patPmtGenerator.GetPat(), TS_SIZE); fileSize += TS_SIZE; int Index = 0; while (uchar *pmt = patPmtGenerator.GetPmt(Index)) { recordFile->Write(pmt, TS_SIZE); fileSize += TS_SIZE; } } if (recordFile->Write(b, Count) < 0) { LOG_ERROR_STR(fileName->Name()); break; } fileSize += Count; t.Set(MAXBROKENTIMEOUT); } } ringBuffer->Del(Count); } } if (t.TimedOut()) { esyslog("ERROR: video data stream broken"); ShutdownHandler.RequestEmergencyExit(); t.Set(MAXBROKENTIMEOUT); } } }
int cScDevices::DvbOpen(const char *Name, int a, int f, int Mode, bool ReportError) { char FileName[128]; DvbName(Name,a,f,FileName,sizeof(FileName)); int fd=open(FileName,Mode); if(fd<0 && ReportError) LOG_ERROR_STR(FileName); return fd; }
static int DvbOpen(const char *Name, int n, int Mode, bool ReportError = false) { const char *FileName = *cDvbName(Name, n); int fd = open(FileName, Mode); if (fd < 0 && ReportError) LOG_ERROR_STR(FileName); return fd; }
int DiskSizeMB(const char *Directory) { int Ret = 0; struct statfs statFs; if (statfs(Directory, &statFs) == 0) { double blocksPerMeg = 1024.0 * 1024.0 / statFs.f_bsize; Ret = int(statFs.f_blocks / blocksPerMeg); } else LOG_ERROR_STR(Directory); return Ret; } // DiskSizeMB
void MessageTable::put(std::string message) { boost::mutex::scoped_lock lock(this->mutex); try { this->messageQueue.push(message); } catch (std::bad_alloc& e) { LOG_ERROR_STR("catch bad_alloc."); } this->condition.notify_all(); }
bool cVideoDirectory::Rename(const char *OldName, const char *NewName) { dsyslog("renaming '%s' to '%s'", OldName, NewName); if (rename(OldName, NewName) == -1) { LOG_ERROR_STR(NewName); return false; } return true; }
bool cPipe::Open(const char *Command, const char *Mode) { int fd[2]; if (pipe(fd) < 0) { LOG_ERROR; return false; } if ((pid = fork()) < 0) { // fork failed LOG_ERROR; close(fd[0]); close(fd[1]); return false; } const char *mode = "w"; int iopipe = 0; if (pid > 0) { // parent process if (strcmp(Mode, "r") == 0) { mode = "r"; iopipe = 1; } close(fd[iopipe]); f = fdopen(fd[1 - iopipe], mode); if ((f = fdopen(fd[1 - iopipe], mode)) == NULL) { LOG_ERROR; close(fd[1 - iopipe]); } return f != NULL; } else { // child process int iofd = STDOUT_FILENO; if (strcmp(Mode, "w") == 0) { mode = "r"; iopipe = 1; iofd = STDIN_FILENO; } close(fd[iopipe]); if (dup2(fd[1 - iopipe], iofd) == -1) { // now redirect LOG_ERROR; close(fd[1 - iopipe]); _exit(-1); } else { int MaxPossibleFileDescriptors = getdtablesize(); for (int i = STDERR_FILENO + 1; i < MaxPossibleFileDescriptors; i++) close(i); //close all dup'ed filedescriptors if (execl("/bin/sh", "sh", "-c", Command, NULL) == -1) { LOG_ERROR_STR(Command); close(fd[1 - iopipe]); _exit(-1); } } _exit(0); } }
uint32_t cHdffCmdIf::CmdOsdCreateDisplay(uint32_t Width, uint32_t Height, HdffColorType_t ColorType) { //printf("CreateDisplay %d %d %d\n", Width, Height, ColorType); uint32_t newDisplay; if (HdffCmdOsdCreateDisplay(mOsdDev, Width, Height, ColorType, &newDisplay) == 0) return newDisplay; LOG_ERROR_STR("Error creating display"); return HDFF_INVALID_HANDLE; }
void ManagerEventsHandler::internalFireEvent(ManagerEvent& me) { LOG_DEBUG_STR("FIRE EVENT " + me.getEventName() + ":: " + me.toLog()); for (EventListenersList::const_iterator iter = listeners.begin(); iter != listeners.end(); ++iter) { try { (const_cast<ManagerEventListener *> (*iter))->onManagerEvent(me); } catch (Exception& E) { LOG_ERROR_STR(E.getMessage()); } } }
void ExceptionHandler::signalHandler(int signal) { #ifdef _WIN32 #else switch (signal) { case SIGSEGV: { LOG_ERROR_STR(ExceptionHandler::getStackTraceString()); LOG_ERROR_STR("Segmentation fault"); exit(0); } break; default: { LOG_ERROR_DATA("Expected: " << SIGSEGV << ", got: " << signal << ", returning"); } break; } #endif }
bool RenameVideoFile(const char *OldName, const char *NewName) { // Only the base video directory entry will be renamed, leaving the // possible symlinks untouched. Going through all the symlinks and disks // would be unnecessary work - maybe later... if (rename(OldName, NewName) == -1) { LOG_ERROR_STR(OldName); return false; } return true; }
uint32_t cHdffCmdIf::CmdOsdCreateFont(uint32_t hFontFace, uint32_t Size) { //printf("CreateFont %d\n", Size); uint32_t newFont; int err; err = HdffCmdOsdCreateFont(mOsdDev, hFontFace, Size, &newFont); if (err == 0) return newFont; LOG_ERROR_STR("Error creating font"); return HDFF_INVALID_HANDLE; }
uint32_t cHdffCmdIf::CmdOsdCreateFontFace(const uint8_t * pFontData, uint32_t DataSize) { //printf("CreateFontFace %d\n", DataSize); uint32_t newFontFace; int err; err = HdffCmdOsdCreateFontFace(mOsdDev, pFontData, DataSize, &newFontFace); if (err == 0) return newFontFace; LOG_ERROR_STR("Error creating font face"); return HDFF_INVALID_HANDLE; }
uint32_t cHdffCmdIf::CmdOsdCreatePalette(HdffColorType_t ColorType, HdffColorFormat_t ColorFormat, uint32_t NumColors, const uint32_t * pColors) { uint32_t newPalette; int err; err = HdffCmdOsdCreatePalette(mOsdDev, ColorType, ColorFormat, NumColors, pColors, &newPalette); if (err == 0) return newPalette; LOG_ERROR_STR("Error creating palette"); return HDFF_INVALID_HANDLE; }
int cKbdRemote::ReadKey(void) { cPoller Poller(STDIN_FILENO); if (Poller.Poll(50)) { uchar ch = 0; int r = safe_read(STDIN_FILENO, &ch, 1); if (r == 1) return ch; if (r < 0) LOG_ERROR_STR("cKbdRemote"); } return -1; }
bool cVideoDirectory::Move(const char *FromName, const char *ToName) { dsyslog("moving '%s' to '%s'", FromName, ToName); if (EntriesOnSameFileSystem(FromName, ToName)) { if (rename(FromName, ToName) == -1) { LOG_ERROR_STR(ToName); return false; } } else return RecordingsHandler.Add(ruMove, FromName, ToName); return true; }
ExceptionHandler::ExceptionHandler() { #ifdef _WIN32 #else struct sigaction newh, oldh; sigset_t sMask; sigemptyset(&sMask); newh.sa_mask = sMask; newh.sa_flags = SA_RESTART | SA_NOMASK; newh.sa_handler = &ExceptionHandler::signalHandler; if (sigaction(SIGSEGV, &newh, &oldh) < 0) { LOG_ERROR_STR("Failed to install signal handler for SIGSEGV"); exit(0); } #endif }
int SystemExec(const char *Command, bool Detached) { isyslog("SystemExec('%s', Detached=%d)", Command, Detached); pid_t pid; if ((pid = fork()) < 0) { // fork failed LOG_ERROR; return -1; } if (pid > 0) { // parent process int status = 0; if (waitpid(pid, &status, 0) < 0) { LOG_ERROR; return -1; } return status; } else { // child process if (Detached) { // Fork again and let first child die - grandchild stays alive without parent if (fork() > 0) _exit(0); // Start a new session pid_t sid = setsid(); if (sid < 0) LOG_ERROR; // close STDIN and re-open as /dev/null int devnull = open("/dev/null", O_RDONLY); if (devnull < 0 || dup2(devnull, 0) < 0) LOG_ERROR; } int MaxPossibleFileDescriptors = getdtablesize(); for (int i = STDERR_FILENO + 1; i < MaxPossibleFileDescriptors; i++) close(i); //close all dup'ed filedescriptors if (execl("/bin/sh", "sh", "-c", Command, NULL) == -1) { LOG_ERROR_STR(Command); _exit(-1); } _exit(0); } }
void cPictureEntry::Load(void) const { if (isDirectory && !entries) { cString Directory = Path(); cReadDir d(Directory); if (d.Ok()) { struct dirent *e; while ((e = d.Next()) != NULL) { struct stat ds; if (stat(AddDirectory(Directory, e->d_name), &ds) == 0) { if (!entries) entries = new cList<cPictureEntry>; entries->Add(new cPictureEntry(e->d_name, this, S_ISDIR(ds.st_mode))); } } if (entries) entries->Sort(); } else LOG_ERROR_STR(*Directory); } }
void cConnectionIGMP::Welcome() { cDevice *device = NULL; if (ProvidesChannel(m_Channel, 0)) device = GetDevice(m_Channel, 0); if (device != NULL) { device->SwitchChannel(m_Channel, false); m_LiveStreamer = new cStreamdevLiveStreamer(0, this); if (m_LiveStreamer->SetChannel(m_Channel, m_StreamType)) { m_LiveStreamer->SetDevice(device); if (!SetDSCP()) LOG_ERROR_STR("unable to set DSCP sockopt"); Dprintf("streamer start\n"); m_LiveStreamer->Start(this); } else { esyslog("streamdev-server IGMP: SetChannel failed"); DELETENULL(m_LiveStreamer); } } else esyslog("streamdev-server IGMP: GetDevice failed"); }
bool cNestedItemList::Load(const char *FileName) { cList<cNestedItem>::Clear(); if (FileName) { free(fileName); fileName = strdup(FileName); } bool result = false; if (fileName && access(fileName, F_OK) == 0) { isyslog("loading %s", fileName); FILE *f = fopen(fileName, "r"); if (f) { int Line = 0; result = Parse(f, this, Line); fclose(f); } else { LOG_ERROR_STR(fileName); result = false; } } return result; }
cUnbufferedFile *OpenVideoFile(const char *FileName, int Flags) { const char *ActualFileName = FileName; // Incoming name must be in base video directory: #ifdef USE_LIVEBUFFER if ((strstr(FileName, VideoDirectory ) != FileName) && (strstr(FileName, BufferDirectory) != FileName)) { #else if (strstr(FileName, VideoDirectory) != FileName) { #endif /*USE_LIVEBUFFER*/ esyslog("ERROR: %s not in %s", FileName, VideoDirectory); errno = ENOENT; // must set 'errno' - any ideas for a better value? return NULL; } // Are we going to create a new file? if ((Flags & O_CREAT) != 0) { cVideoDirectory Dir; if (Dir.IsDistributed()) { #ifdef USE_DVLVIDPREFER if (Setup.UseVidPrefer == 0) { #endif /* DVLVIDPREFER */ // Find the directory with the most free space: int MaxFree = Dir.FreeMB(); while (Dir.Next()) { int Free = FreeDiskSpaceMB(Dir.Name()); if (Free > MaxFree) { Dir.Store(); MaxFree = Free; } } #ifdef USE_DVLVIDPREFER } else Dir.GetPreferedVideoDir(); #endif /* DVLVIDPREFER */ if (Dir.Stored()) { ActualFileName = Dir.Adjust(FileName); if (!MakeDirs(ActualFileName, false)) return NULL; // errno has been set by MakeDirs() #ifdef USE_DVLVIDPREFER if (strcmp(ActualFileName, FileName) != 0) { #endif /* DVLVIDPREFER */ if (symlink(ActualFileName, FileName) < 0) { LOG_ERROR_STR(FileName); return NULL; } #ifdef USE_DVLVIDPREFER } #endif /* DVLVIDPREFER */ ActualFileName = strdup(ActualFileName); // must survive Dir! } } } cUnbufferedFile *File = cUnbufferedFile::Create(ActualFileName, Flags, DEFFILEMODE); if (ActualFileName != FileName) free((char *)ActualFileName); return File; } int CloseVideoFile(cUnbufferedFile *File) { int Result = File->Close(); delete File; return Result; }
bool cRecorder::NextFile(void) { if (recordFile && frameDetector->IndependentFrame()) { // every file shall start with an independent frame #ifdef USE_HARDLINKCUTTER if (fileSize > fileName->MaxFileSize() || RunningLowOnDiskSpace()) { #else if (fileSize > MEGABYTE(off_t(Setup.MaxVideoFileSize)) || RunningLowOnDiskSpace()) { #endif /* HARDLINKCUTTER */ recordFile = fileName->NextFile(); fileSize = 0; } } return recordFile != NULL; } void cRecorder::Activate(bool On) { if (On) Start(); else Cancel(3); } void cRecorder::Receive(uchar *Data, int Length) { if (Running()) { int p = ringBuffer->Put(Data, Length); if (p != Length && Running()) ringBuffer->ReportOverflow(Length - p); } } void cRecorder::Action(void) { time_t t = time(NULL); bool InfoWritten = false; bool FirstIframeSeen = false; #ifdef USE_LIVEBUFFER double fps = DEFAULTFRAMESPERSECOND; #endif /*USE_LIVEBUFFER*/ while (Running()) { int r; uchar *b = ringBuffer->Get(r); if (b) { int Count = frameDetector->Analyze(b, r); if (Count) { if (!Running() && frameDetector->IndependentFrame()) // finish the recording before the next independent frame break; if (frameDetector->Synced()) { #ifdef USE_LIVEBUFFER if(index && (frameDetector->FramesPerSecond() != fps)) { fps = frameDetector->FramesPerSecond(); index->SetFramesPerSecond(fps); } // if #endif /*USE_LIVEBUFFER*/ if (!InfoWritten) { cRecordingInfo RecordingInfo(recordingName); if (RecordingInfo.Read()) { if (frameDetector->FramesPerSecond() > 0 && DoubleEqual(RecordingInfo.FramesPerSecond(), DEFAULTFRAMESPERSECOND) && !DoubleEqual(RecordingInfo.FramesPerSecond(), frameDetector->FramesPerSecond())) { RecordingInfo.SetFramesPerSecond(frameDetector->FramesPerSecond()); RecordingInfo.Write(); Recordings.UpdateByName(recordingName); } } InfoWritten = true; } /* if (frameDetector->NewPayload()) { // We're at the first TS packet of a new payload... if (Buffering) esyslog("ERROR: encountered new payload while buffering - dropping some data!"); if (!frameDetector->NewFrame()) { // ...but the frame type is yet unknown, so we need to buffer packets until we see the frame type if (!Buffer) { dsyslog("frame type not in first packet of payload - buffering"); if (!(Buffer = MALLOC(uchar, BUFFERSIZE))) { esyslog("ERROR: can't allocate frame type buffer"); break; } } BufferIndex = 0; Buffering = true; } } else if (frameDetector->NewFrame()) // now we know the frame type, so stop buffering Buffering = false; if (Buffering) { if (BufferIndex + Count <= BUFFERSIZE) { memcpy(Buffer + BufferIndex, b, Count); BufferIndex += Count; } else esyslog("ERROR: too many bytes for frame type buffer (%d > %d) - dropped %d bytes", BufferIndex + Count, int(BUFFERSIZE), Count); } else if (FirstIframeSeen || frameDetector->IndependentFrame()) { */ #ifdef USE_LIVEBUFFER if(!FirstIframeSeen) FillInitialData(b, r); #endif /*USE_LIVEBUFFER*/ if (FirstIframeSeen || frameDetector->IndependentFrame()) { FirstIframeSeen = true; // start recording with the first I-frame if (!NextFile()) break; if (index && frameDetector->NewFrame()) index->Write(frameDetector->IndependentFrame(), fileName->Number(), fileSize); if (frameDetector->IndependentFrame()) { recordFile->Write(patPmtGenerator.GetPat(), TS_SIZE); fileSize += TS_SIZE; int Index = 0; while (uchar *pmt = patPmtGenerator.GetPmt(Index)) { recordFile->Write(pmt, TS_SIZE); fileSize += TS_SIZE; } } if (recordFile->Write(b, Count) < 0) { LOG_ERROR_STR(fileName->Name()); break; } fileSize += Count; t = time(NULL); } } ringBuffer->Del(Count); } } #ifdef USE_LIVEBUFFER if (handleError && (time(NULL) - t > MAXBROKENTIMEOUT)) { #else if (time(NULL) - t > MAXBROKENTIMEOUT) { #endif #if REELVDR Skins.QueueMessage(mtError, tr("can't record - check your configuration")); #else esyslog("ERROR: video data stream broken. Requesting Emergency Exit."); ShutdownHandler.RequestEmergencyExit(); #endif /*REELVDR*/ t = time(NULL); } } }
bool HardLinkVideoFile(const char *OldName, const char *NewName) { // Incoming name must be in base video directory: if (strstr(OldName, VideoDirectory) != OldName) { esyslog("ERROR: %s not in %s", OldName, VideoDirectory); return false; } if (strstr(NewName, VideoDirectory) != NewName) { esyslog("ERROR: %s not in %s", NewName, VideoDirectory); return false; } const char *ActualNewName = NewName; cString ActualOldName(ReadLink(OldName), true); // Some safety checks: struct stat StatOldName; if (lstat(ActualOldName, &StatOldName) == 0) { if (S_ISLNK(StatOldName.st_mode)) { esyslog("HardLinkVideoFile: Failed to resolve symbolic link %s", (const char*)ActualOldName); return false; } } else { esyslog("HardLinkVideoFile: lstat failed on %s", (const char*)ActualOldName); return false; } isyslog("HardLinkVideoFile: %s is on %i", (const char*)ActualOldName, (int)StatOldName.st_dev); // Find the video directory where ActualOldName is located cVideoDirectory Dir; struct stat StatDir; if (!StatNearestDir(NewName, &StatDir)) { esyslog("HardLinkVideoFile: stat failed on %s", NewName); return false; } isyslog("HardLinkVideoFile: %s is on %i", NewName, (int)StatDir.st_dev); if (StatDir.st_dev != StatOldName.st_dev) { // Not yet found. if (!Dir.IsDistributed()) { esyslog("HardLinkVideoFile: No matching video folder to hard link %s", (const char*)ActualOldName); return false; } // Search in video01 and upwards bool found = false; while (Dir.Next()) { Dir.Store(); const char *TmpNewName = Dir.Adjust(NewName); if (StatNearestDir(TmpNewName, &StatDir) && StatDir.st_dev == StatOldName.st_dev) { isyslog("HardLinkVideoFile: %s is on %i (match)", TmpNewName, (int)StatDir.st_dev); ActualNewName = TmpNewName; found = true; break; } isyslog("HardLinkVideoFile: %s is on %i", TmpNewName, (int)StatDir.st_dev); } if (ActualNewName == NewName) { esyslog("HardLinkVideoFile: No matching video folder to hard link %s", (const char*)ActualOldName); return false; } // Looking good, we have a match. Create necessary folders. if (!MakeDirs(ActualNewName, false)) return false; // There's no guarantee that the directory of ActualNewName // is on the same device as the dir that StatNearestDir found. // But worst case is that the link fails. } #ifdef HARDLINK_TEST_ONLY // Do the hard link to *.vdr_ for testing only char *name = NULL; asprintf(&name, "%s_",ActualNewName); link(ActualOldName, name); free(name); return false; #endif // HARDLINK_TEST_ONLY // Try creating the hard link if (link(ActualOldName, ActualNewName) != 0) { // Failed to hard link. Maybe not allowed on file system. LOG_ERROR_STR(ActualNewName); isyslog("HardLinkVideoFile: failed to hard link from %s to %s", (const char*)ActualOldName, ActualNewName); return false; } if (ActualNewName != NewName) { // video01 and up. Do the remaining symlink if (symlink(ActualNewName, NewName) < 0) { LOG_ERROR_STR(NewName); return false; } } return true; }
bool cTheme::Load(const char *FileName, bool OnlyDescriptions) { if (!FileNameOk(FileName, true)) return false; bool result = false; if (!OnlyDescriptions) isyslog("loading %s", FileName); FILE *f = fopen(FileName, "r"); if (f) { int line = 0; result = true; char *s; const char *error = NULL; cReadLine ReadLine; while ((s = ReadLine.Read(f)) != NULL) { line++; char *p = strchr(s, '#'); if (p) *p = 0; s = stripspace(skipspace(s)); if (!isempty(s)) { char *n = s; char *v = strchr(s, '='); if (v) { *v++ = 0; n = stripspace(skipspace(n)); v = stripspace(skipspace(v)); if (strstr(n, "Description") == n) { int lang = 0; char *l = strchr(n, '.'); if (l) lang = I18nLanguageIndex(++l); if (lang >= 0) { free(descriptions[lang]); descriptions[lang] = strdup(v); } else error = "invalid language code"; } else if (!OnlyDescriptions) { for (int i = 0; i < MaxThemeColors; i++) { if (colorNames[i]) { if (strcmp(n, colorNames[i]) == 0) { char *p = NULL; errno = 0; tColor c = strtoul(v, &p, 16); if (!errno && !*p) colorValues[i] = c; else error = "invalid color value"; break; } } else { error = "unknown color name"; break; } } } } else error = "missing value"; } if (error) { result = false; break; } } if (!result) esyslog("ERROR: error in %s, line %d%s%s", FileName, line, error ? ": " : "", error ? error : ""); fclose(f); } else LOG_ERROR_STR(FileName); return result; }