You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kile/src/kile/kilelyxserver.cpp

235 lines
6.3 KiB

/***************************************************************************
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 <sys/stat.h>
#include <stdlib.h> //getenv
#include <unistd.h> //read
#include <fcntl.h>
#include "kileactions.h"
#include <tqfile.h>
#include <tqfileinfo.h>
#include <tqsocketnotifier.h>
#include <tqregexp.h>
#include <tqdir.h>
#include "kiledebug.h"
#include <tdelocale.h>
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<TQFile> it(m_pipeIn);
while (it.current())
{
if ((*it)->name().right(3) == ".in" )
{
notifier = new TQSocketNotifier((*it)->handle(), TQSocketNotifier::Read, this);
connect(notifier, TQ_SIGNAL(activated(int)), this, TQ_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<TQFile> 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.find(reCite) != -1 )
emit(insert(KileAction::TagData(i18n("Cite"), "\\cite{"+reCite.cap(1)+'}')));
else if( line.find(reBibtexdbadd) != -1 )
emit(insert(KileAction::TagData(i18n("BibTeX db add"), "\\bibliography{"+ reBibtexdbadd.cap(1) + '}')));
else if( line.find(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"