Files
libreoffice/extensions/source/nsplugin/source/so_main.cxx
Ivo Hinkelmann 8cb15f1b94 INTEGRATION: CWS wae4extensions (1.6.8); FILE MERGED
2007/10/01 12:00:05 fs 1.6.8.3: #i81612# warning-free code (unxsoli4)
2007/10/01 10:34:36 fs 1.6.8.2: #i81612# warning-free code (unxlngi6)
2007/09/27 10:20:00 fs 1.6.8.1: #i81612# warning-free code
2008-01-14 13:45:52 +00:00

404 lines
11 KiB
C++

/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: so_main.cxx,v $
*
* $Revision: 1.7 $
*
* last change: $Author: ihi $ $Date: 2008-01-14 14:45:52 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2005 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"
#ifdef UNIX
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#endif //end of UNIX
#ifdef WNT
#ifdef _MSC_VER
#pragma once
#endif
#pragma warning (push,1)
#pragma warning (disable:4668)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#pragma warning (pop)
#endif //end of WNT
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "ns_debug.hxx"
#include "so_msg.hxx"
#include "so_instance.hxx"
#include "so_env.hxx"
#include "nsp_func.hxx"
#define MAX_NODE_NUM 1024
SoPluginInstance* lpInstance[MAX_NODE_NUM];
long int NSP_ReadFromPipe(NSP_PIPE_FD fp, void* buf, unsigned long int len)
{
unsigned long int len_unix = 0, len_wnt = 0;
len_unix = NSP_Read_Pipe(fp, buf, len, &len_wnt);
#ifdef UNIX
(void)len_wnt;
return len_unix;
#endif //end of UNIX
#ifdef WNT
return len_wnt;
#endif //end of WNT
}
int find_free_node()
{
for(int i=0; i<MAX_NODE_NUM; i++)
{
if(NULL == lpInstance[i])
return i;
}
return -1;
}
int find_cur_node(sal_Int32 cur_id)
{
for(int i=0; i<MAX_NODE_NUM; i++)
{
if(lpInstance[i] == NULL)
continue;
if(cur_id == lpInstance[i]->GetParent())
return i;
}
return -1;
}
sal_Bool dump_plugin_message(PLUGIN_MSG* pMsg)
{
if (!pMsg)
return sal_False;
debug_fprintf(NSP_LOG_APPEND, "NSPlugin Message: msg_id:%d; instance_id:%d;wnd_id:%d;wnd_x:%d;wnd_y:%d;wnd_w:%d;wnd_h:%d; url:%s\n",
pMsg->msg_id, pMsg->instance_id, pMsg->wnd_id,
pMsg->wnd_x, pMsg->wnd_y, pMsg->wnd_w, pMsg->wnd_h, pMsg->url);
return sal_True;
}
int prepareEnviron()
{
// if child process inherit the chdir() property from parent process, if yes, no getNewLibraryPath() needed
const char* pNewLibraryPath = getNewLibraryPath();
putenv( (char*) pNewLibraryPath );
SoPluginInstance::SetSODir((char *)findProgramDir());
return 0;
}
int Set_Window(PLUGIN_MSG* pMsg)
{
dump_plugin_message(pMsg);
int cur_no;
if( -1 == (cur_no = find_cur_node(pMsg->instance_id)))
return -1;
if(lpInstance[cur_no]->SetWindow(pMsg->wnd_id,
pMsg->wnd_x, pMsg->wnd_y, pMsg->wnd_w, pMsg->wnd_h))
return 0;
else
return -1;
}
int Set_URL(PLUGIN_MSG* pMsg)
{
dump_plugin_message(pMsg);
int cur_no;
if( -1 == (cur_no = find_cur_node(pMsg->instance_id)))
return -1;
if(lpInstance[cur_no]->SetURL(pMsg->url))
return 0;
else
return -1;
}
int New_Instance(PLUGIN_MSG* pMsg)
{
dump_plugin_message(pMsg);
int free_no;
if( -1 == (free_no = find_free_node()))
return -1;
lpInstance[free_no] = new SoPluginInstance(pMsg->instance_id);
return 0;
}
int Destroy(PLUGIN_MSG* pMsg)
{
dump_plugin_message(pMsg);
int cur_no;
if( -1 == (cur_no = find_cur_node(pMsg->instance_id)))
return -1;
if(lpInstance[cur_no] != NULL)
{
lpInstance[cur_no]->Destroy();
debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, begin delete.\n");
delete(lpInstance[cur_no]);
lpInstance[cur_no] = NULL;
}
return 0;
}
int Print(PLUGIN_MSG* pMsg)
{
dump_plugin_message(pMsg);
int cur_no;
if( -1 == (cur_no = find_cur_node(pMsg->instance_id)))
return -1;
if(lpInstance[cur_no] != NULL)
{
lpInstance[cur_no]->Print();
}
return 0;
}
int Shutdown()
{
for(int cur_no=0; cur_no<MAX_NODE_NUM; cur_no++)
{
if(lpInstance[cur_no] == NULL)
continue;
lpInstance[cur_no]->Destroy();
debug_fprintf(NSP_LOG_APPEND, "print by Nsplugin, begin delete.\n");
delete(lpInstance[cur_no]);
lpInstance[cur_no] = NULL;
}
return -1;
}
int dispatchMsg(PLUGIN_MSG* pMsg)
{
switch(pMsg->msg_id)
{
case SO_SET_WINDOW:
return Set_Window(pMsg);
case SO_NEW_INSTANCE:
return New_Instance(pMsg);
case SO_SET_URL:
return Set_URL(pMsg);
case SO_DESTROY:
return Destroy(pMsg);
case SO_SHUTDOWN:
Shutdown();
return -1;
case SO_PRINT:
Print(pMsg);
return 0;
default:
return -1;
}
}
sal_Bool start_office(NSP_PIPE_FD read_fd)
{
int my_sock;
struct sockaddr_in dst_addr;
char sCommand[NPP_PATH_MAX];
sCommand[0] = 0;
#ifdef WNT
{
WSADATA wsaData;
WORD wVersionRequested;
wVersionRequested = MAKEWORD(2,0);
if(WSAStartup(wVersionRequested, &wsaData))
{
NSP_Close_Pipe(read_fd);
debug_fprintf(NSP_LOG_APPEND, "Can not init socket in Windows.\n");
return sal_False;
}
}
#endif //end of WNT
memset(&dst_addr, 0, sizeof(dst_addr));
dst_addr.sin_family = AF_INET;
dst_addr.sin_port = htons(SO_SERVER_PORT);
dst_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
int count = 0;
int ret = 0;
my_sock=socket(PF_INET, SOCK_STREAM, 0);
// if Star Office has been stared, we need not to start it again
ret = connect(my_sock, (struct sockaddr *)&dst_addr, sizeof(dst_addr));
if(ret == 0)
{
NSP_CloseSocket(my_sock);
debug_fprintf(NSP_LOG_APPEND, "Staroffice already start\n");
return sal_True;
}
{
debug_fprintf(NSP_LOG_APPEND, "try to star Staroffice\n");
char para[128] = {0};
sprintf(para, "-accept=socket,host=0,port=%d;urp", SO_SERVER_PORT);
#ifdef UNIX
int nChildPID = fork();
if( ! nChildPID ) // child process
{
NSP_CloseSocket(my_sock);
NSP_Close_Pipe(read_fd);
sprintf(sCommand, "/bin/sh soffice -nologo -nodefault %s", para);
debug_fprintf(NSP_LOG_APPEND,"StarOffice will be started by command: %s\n",sCommand);
execl("/bin/sh", "/bin/sh", "soffice", "-nologo", "-nodefault", para, NULL);
_exit(255);
}
#endif //end of UNIX
#ifdef WNT
STARTUPINFO NSP_StarInfo;
memset((void*) &NSP_StarInfo, 0, sizeof(STARTUPINFO));
NSP_StarInfo.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION NSP_ProcessInfo;
memset((void*)&NSP_ProcessInfo, 0, sizeof(PROCESS_INFORMATION));
sprintf(para, " -nologo -nodefault -accept=socket,host=0,port=%d;urp", SO_SERVER_PORT);
//sprintf(para, " -accept=socket,host=0,port=%d;urp\n", SO_SERVER_PORT);
SECURITY_ATTRIBUTES NSP_access = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE}; (void)NSP_access;
sprintf(sCommand, "\"%s\" %s", findSofficeExecutable(), para);
debug_fprintf(NSP_LOG_APPEND,"StarOffice will be started by command: %s",sCommand);
BOOL ret = false;
ret = CreateProcess(findSofficeExecutable(), sCommand, NULL, NULL, FALSE,
0 , NULL, NULL, &NSP_StarInfo, &NSP_ProcessInfo);
if(ret==false){
debug_fprintf(NSP_LOG_APPEND,"run staroffice error: %u \n",
GetLastError());
}
else debug_fprintf(NSP_LOG_APPEND,"run staroffice success\n");
#endif //end of WNT
}
NSP_Sleep(5);
// try to connect to background SO, thus judge if it is ready
while(0 > connect(my_sock, (struct sockaddr *)&dst_addr, sizeof(dst_addr)))
{
NSP_Sleep(1);
if (count++ >= 120)
{
NSP_CloseSocket(my_sock);
debug_fprintf(NSP_LOG_APPEND, "print by nsplugin, con star remote StarOffice\n");
return sal_False;
}
debug_fprintf(NSP_LOG_APPEND, "print by nsplugin, Current count: %d\n", count);
}
NSP_CloseSocket(my_sock);
NSP_Sleep(5);
prepareEnviron();
return sal_True;
}
static NSP_PIPE_FD la_read_fd = 0;
int main(int argc, char** argv)
{
// Sleep(20*1000);
debug_fprintf(NSP_LOG_APPEND, "start of main\n");
memset(lpInstance, 0, sizeof(lpInstance));
NSP_PIPE_FD fd_pipe[2];
int iPipe[2];
#ifdef UNIX
if(argc < 3)
{
debug_fprintf(NSP_LOG_APPEND, "print by nsplugin, command error; too little argument to start plugin exec\n");
return sal_False;
}
iPipe[0] = atoi(argv[1]);
iPipe[1] = atoi(argv[2]);
#endif //end of UNIX
#ifdef WNT
(void)argc;
//sscanf( GetCommandLine(), "%d %d", &iPipe[0], &iPipe[1] );
iPipe[0] = atoi(argv[0]);
iPipe[1] = atoi(argv[1]);
#endif //end of WNT
// fd_pipe[0]: read, fd_pipe[0]: write
fd_pipe[0] = (NSP_PIPE_FD) iPipe[0] ;
fd_pipe[1] = (NSP_PIPE_FD) iPipe[1] ;
NSP_Close_Pipe(fd_pipe[1]);
la_read_fd = fd_pipe[0];
if(la_read_fd < 0)
{
debug_fprintf(NSP_LOG_APPEND, "print by nsplugin, command error: bad read file id:%s \n", la_read_fd);
return 0;
}
if(!start_office(la_read_fd))
{
NSP_Close_Pipe(la_read_fd);
return -1;
}
PLUGIN_MSG nMsg;
int len;
while(1)
{
memset(&nMsg, 0, sizeof(PLUGIN_MSG));
len = NSP_ReadFromPipe(la_read_fd, (char*)&nMsg, sizeof(PLUGIN_MSG));
if(len != sizeof(PLUGIN_MSG))
break;
debug_fprintf(NSP_LOG_APPEND, "Read message from pipe type %d \n", nMsg.msg_id);
if(-1 == dispatchMsg(&nMsg))
{
debug_fprintf(NSP_LOG_APPEND, "plugin will shutdown\n");
break;
}
}
NSP_Close_Pipe(la_read_fd);
_exit(0);
}
extern "C"{
sal_Bool restart_office(void){
return start_office(la_read_fd);
}
}