/*************************************************************************** begin : Sat Sept 9 2003 edit : Tue Mar 20 2007 copyright : (C) 2003 by Jeroen Wijnhout, 2007 by Thomas Braun email : Jeroen.Wijnhout@kdemail.net ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "kilelyxserver.h" #include #include //getenv #include //read #include #include "kileactions.h" #include #include #include #include #include #include "kiledebug.h" #include KileLyxServer::KileLyxServer(bool startMe) : m_perms( S_IRUSR | S_IWUSR ),m_running(false) { KILE_DEBUG() << "===KileLyxServer::KileLyxServer(bool" << startMe << ")===" << endl; m_pipeIn.setAutoDelete(true); m_notifier.setAutoDelete(true); m_file.setAutoDelete(false); m_tempDir = new KTempDir(); if(!m_tempDir) return; m_tempDir->setAutoDelete(true); m_links << ".lyxpipe.in" << ".lyx/lyxpipe.in"; m_links << ".lyxpipe.out" << ".lyx/lyxpipe.out"; for(uint i = 0; i< m_links.count() ; i++) { m_pipes.append( m_tempDir->name() + m_links[i] ); m_links[i].prepend(TQDir::homeDirPath() + '/' ); KILE_DEBUG() << "m_pipes[" << i << "]=" << m_pipes[i] << endl; KILE_DEBUG() << "m_links[" << i << "]=" << m_links[i] << endl; } if (startMe) start(); } KileLyxServer::~KileLyxServer() { stop(); removePipes(); delete m_tempDir; } bool KileLyxServer::start() { if (m_running) stop(); KILE_DEBUG() << "Starting the LyX server..." << endl; if (openPipes()) { TQSocketNotifier *notifier; TQPtrListIterator it(m_pipeIn); while (it.current()) { if ((*it)->name().right(3) == ".in" ) { notifier = new TQSocketNotifier((*it)->handle(), TQSocketNotifier::Read, this); connect(notifier, TQT_SIGNAL(activated(int)), this, TQT_SLOT(receive(int))); m_notifier.append(notifier); KILE_DEBUG() << "Created notifier for " << (*it)->name() << endl; } else KILE_DEBUG() << "No notifier created for " << (*it)->name() << endl; ++it; } m_running=true; } return m_running; } bool KileLyxServer::openPipes() { KILE_DEBUG() << "===bool KileLyxServer::openPipes()===" << endl; bool opened = false; TQFileInfo pipeInfo,linkInfo; TQFile *file; struct stat buf; struct stat *stats = &buf; for (uint i=0; i < m_pipes.count(); ++i) { pipeInfo.setFile(m_pipes[i]); linkInfo.setFile(m_links[i]); TQFile::remove(linkInfo.absFilePath()); linkInfo.refresh(); if ( !pipeInfo.exists() ) { //create the dir first if ( !TQFileInfo(pipeInfo.dirPath(true)).exists() ) if ( mkdir(TQFile::encodeName( pipeInfo.dirPath() ), m_perms | S_IXUSR) == -1 ) { kdError() << "Could not create directory for pipe" << endl; continue; } else KILE_DEBUG() << "Created directory " << pipeInfo.dirPath() << endl; if ( mkfifo(TQFile::encodeName( pipeInfo.absFilePath() ), m_perms) != 0 ) { kdError() << "Could not create pipe: " << pipeInfo.absFilePath() << endl; continue; } else KILE_DEBUG() << "Created pipe: " << pipeInfo.absFilePath() << endl; } if ( symlink(TQFile::encodeName(pipeInfo.absFilePath()),TQFile::encodeName(linkInfo.absFilePath())) != 0 ) { kdError() << "Could not create symlink: " << linkInfo.absFilePath() << " --> " << pipeInfo.absFilePath() << endl; continue; } file = new TQFile(pipeInfo.absFilePath()); pipeInfo.refresh(); if( pipeInfo.exists() && file->open(IO_ReadWrite) ) // in that order we don't create the file if it does not exist { KILE_DEBUG() << "Opened file: " << pipeInfo.absFilePath() << endl; fstat(file->handle(),stats); if( !S_ISFIFO(stats->st_mode) ) { kdError() << "The file " << pipeInfo.absFilePath() << "we just created is not a pipe!" << endl; file->close(); delete file; continue; } else { // everything is correct :) m_pipeIn.append(file); m_file.insert(file->handle(),file); opened=true; } } else { kdError() << "Could not open " << pipeInfo.absFilePath() << endl; delete file; } } return opened; } void KileLyxServer::stop() { KILE_DEBUG() << "Stopping the LyX server..." << endl; TQPtrListIterator it(m_pipeIn); while (it.current()) { (*it)->close(); ++it; } m_pipeIn.clear(); m_notifier.clear(); m_running=false; } void KileLyxServer::removePipes() { for ( uint i = 0; i < m_links.count(); ++i) TQFile::remove(m_links[i]); for ( uint i = 0; i < m_pipes.count(); ++i) TQFile::remove(m_pipes[i]); } void KileLyxServer::processLine(const TQString &line) { KILE_DEBUG() << "===void KileLyxServer::processLine(const TQString " << line << ")===" << endl; TQRegExp reCite(":citation-insert:(.*)$"); TQRegExp reBibtexdbadd(":bibtex-database-add:(.*)$"); TQRegExp rePaste(":paste:(.*)$"); if( line.tqfind(reCite) != -1 ) emit(insert(KileAction::TagData(i18n("Cite"), "\\cite{"+reCite.cap(1)+'}'))); else if( line.tqfind(reBibtexdbadd) != -1 ) emit(insert(KileAction::TagData(i18n("BibTeX db add"), "\\bibliography{"+ reBibtexdbadd.cap(1) + '}'))); else if( line.tqfind(rePaste) != -1) emit(insert(KileAction::TagData(i18n("Paste"), rePaste.cap(1)))); } void KileLyxServer::receive(int fd) { if (m_file[fd]) { int bytesRead; int const size = 256; char buffer[size]; if ((bytesRead = read(fd, buffer, size - 1)) > 0 ) { buffer[bytesRead] = '\0'; // turn it into a c string TQStringList cmds = TQStringList::split('\n', TQString(buffer).stripWhiteSpace()); for ( uint i = 0; i < cmds.count(); ++i ) processLine(cmds[i]); } } } #include "kilelyxserver.moc"