tinycobol/lib/flckclient.c

854 lines
23 KiB
C

/*
* Copyright (C) 2003 Andrew Cameron
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1,
* or (at your option) any later version.
*
* 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; see the file COPYING.LIB. If
* not, write to the Free Software Foundation, Inc., 59 Temple Place,
* Suite 330, Boston, MA 02111-1307 USA
*/
#include "htcoblib.h"
#ifdef USE_LOCKSERVER
#include "flckclient.h"
struct fd_filename name_info[NO_OF_FILES];
char *temp_key;
/* This is the host that runs the Lockserver */
char *lockserverhost="localhost";
#ifdef __MINGW32__
char *realpath(const char *filename, char *pathbuf)
{
char buf[MAX_PATH];
char* finalpart;
DWORD len = GetFullPathName (filename, MAX_PATH, buf, &finalpart);
if (len == 0 || len > MAX_PATH-1) /* failure */
{
strcpy(pathbuf, filename);
return strdup (filename);
}
else
{
strcpy(pathbuf, buf);
return strdup (buf);
}
}
int write_socket(SOCKET s, const char *buf, int len)
{
int result;
result = send(s,buf,len,0);
return result;
}
int read_socket(SOCKET s, char *buf, int len)
{
int result;
result = recv(s,buf,len,0);
return result;
}
int init_socket()
{
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{ /* Tell the user that we could not find a usable */
/* WinSock DLL. */
perror("Unable to find a Suitable Winsock DLL\n");
}
/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
perror("Unable to find a Suitable Winsock DLL\n");
} /* The WinSock DLL is acceptable. Proceed. */
return 0;
}
#endif
/*------------------------------------------------------------------------*\
| |
| set_lockserver_lock |
| |
\*------------------------------------------------------------------------*/
int set_lockserver_lock( char *filename, char *key)
{
/******************************************************************************/
/* This routine will connect to the Lockserver process and request a lock for */
/* A givein filename, key pair. The filename should be the full name of the */
/* of the file ie /home/andrew/names.db. The Key should be the PRIMARY key in */
/* the Datafile and not an Alternate Key. */
/* If the lock is granted it will retun 0 otherwise it will return 1 */
/******************************************************************************/
struct hostent *hp;
struct sockaddr_in sin;
char buf[TCOB_MAX_PATHLN];
#ifndef __MINGW32__
int s;
#else
SOCKET s;
#endif
int command;
int j;
pid_t mypid;
unsigned int mask;
#ifdef __MINGW32__
init_socket();
#endif
/* Translate host name into peer's IP address */
if ((hp = gethostbyname(lockserverhost)) == NULL) {
fprintf(stderr, "unknown host %s\n",lockserverhost);
exit(1);
}
/*
* Initialize the address data structure
*/
memset((void *)&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
memcpy((void *)&sin.sin_addr, hp->h_addr, hp->h_length);
sin.sin_port = htons(SERVER_PORT);
/*
* Create a socket
*/
if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
perror("socket");
exit(1);
}
/*
* Create a connection between the socket and the server
*/
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
perror("connect: Check that Lockserver is running");
exit(1);
}
/* Get Connection Result
*/;
recv(s, buf, 1, 0);
if(buf[0] < 1) {
perror("Access Denied: Check that your IP is defined in the hosts file");
exit(1);
}
// Set Command to Request a Lock
command=0x2;
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Length of Key
command=strlen(filename);
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Key
#ifndef __MINGW32__
write(s, filename, command);
#else
write_socket(s, filename, command);
#endif
//Length of Index
command=strlen(key);
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Index
#ifndef __MINGW32__
write(s, key, command);
#else
write_socket(s, key, command);
#endif
//Get My PID and use it as owner
mypid = getpid();
sprintf(buf,"%i",mypid);
//Length of Owner
command=strlen(buf);
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Owner
#ifndef __MINGW32__
write(s, buf,command);
#else
write_socket(s, buf,command);
#endif
//TTL
command=65535;
mask=0xff00;
j=((command & mask) >> 8);
#ifndef __MINGW32__
write(s, &j, 1);
#else
write_socket(s, &j, 1);
#endif
mask=0xff;
j=command & mask;
#ifndef __MINGW32__
write(s, &j, 1);
#else
write_socket(s, &j, 1);
#endif
//TTW
command=1;
mask=0xff00;
j=((command & mask) >> 8);
#ifndef __MINGW32__
write(s, &j, 1);
#else
write_socket(s, &j, 1);
#endif
mask=0xff;
j=command & mask;
#ifndef __MINGW32__
write(s, &j, 1);
#else
write_socket(s, &j, 1);
#endif
//Pri
command=0x1;
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//end
//Get 2 Byte Int Response.
#ifndef __MINGW32__
read(s, &command, 1);
#else
read_socket(s, &command, 1);
#endif
command = command << 8;
#ifndef __MINGW32__
read(s, &command, 1);
#else
read_socket(s, &command, 1);
#endif
#ifndef __MINGW32__
close(s);
#else
closesocket(s);
WSACleanup();
#endif
if(command == 1)
return(0);
else
return(1);
}
/*------------------------------------------------------------------------*\
| |
| get_lockserver_lock_owner |
| |
\*------------------------------------------------------------------------*/
int get_lockserver_lock_owner( char *filename, char *key)
{
/******************************************************************************/
/* This routine will connect to the Lockserver process and see if a record is */
/* locked for a given filename, ker pair. */
/* The filename should be the full name of the */
/* of the file ie /home/andrew/names.db. The Key should be the PRIMARY key in */
/* the Datafile and not an Alternate Key. */
/* If the record is locked it by another process it will retun 1 otherwise it */
/* will return 0 */
/******************************************************************************/
struct hostent *hp;
struct sockaddr_in sin;
char buf[TCOB_MAX_PATHLN];
#ifndef __MINGW32__
int s;
#else
SOCKET s;
#endif
int command;
int cmp;
int len;
pid_t mypid;
char *owner;
#ifdef __MINGW32__
init_socket();
#endif
/* Translate host name into peer's IP address */
if ((hp = gethostbyname(lockserverhost)) == NULL) {
fprintf(stderr, "unknown host %s\n",lockserverhost);
exit(1);
}
/*
* Initialize the address data structure
*/
memset((void *)&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
memcpy((void *)&sin.sin_addr, hp->h_addr, hp->h_length);
sin.sin_port = htons(SERVER_PORT);
/*
* Create a socket
*/
if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
perror("socket");
exit(1);
}
/*
* Create a connection between the socket and the server
*/
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
perror("connect: Check that Lockserver is running");
exit(1);
}
/* Get Connection Result
*/;
recv(s, buf, 1,0);
if(buf[0] < 1) {
perror("Access Denied: Check that your IP is defined in the hosts file");
exit(1);
}
// Set Command to Find a Lock Ownerk
command=0x1;
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Length of Key
command=strlen(filename);
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Key
#ifndef __MINGW32__
write(s, filename, command);
#else
write_socket(s, filename, command);
#endif
//Length of Index
command=strlen(key);
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Index
#ifndef __MINGW32__
write(s, key, command);
#else
write_socket(s, key, command);
#endif
//Get My PID
mypid = getpid();
sprintf(buf,"%i",mypid);
//Get Owner
#ifndef __MINGW32__
read(s, &command, 1);
#else
read_socket(s, &command, 1);
#endif
owner = (char *) malloc (sizeof(char) * (command + 1));
#ifndef __MINGW32__
read(s, owner, command);
#else
read_socket(s, owner, command);
#endif
owner[command] = '\0';
#ifndef __MINGW32__
close(s);
#else
closesocket(s);
WSACleanup();
#endif
if(command > 0)
{
len = strlen(owner);
cmp=(strncmp(buf,owner,len));
if (cmp == 0)
{
free(owner);
return(0);
}
else
{
free(owner);
return(1);
}
}
else
{
free(owner);
return(0);
}
}
/*------------------------------------------------------------------------*\
| |
| lockserver_release_specific_lock |
| |
\*------------------------------------------------------------------------*/
int lockserver_release_specific_lock( char *filename, char *key)
{
/******************************************************************************/
/* This routine will connect to the Lockserver process and release a specific */
/* lock for a given filename, ker pair. If key is "*" it will release all */
/* records for that filename. */
/* The filename should be the full name of the */
/* of the file ie /home/andrew/names.db. The Key should be the PRIMARY key in */
/* the Datafile and not an Alternate Key. */
/* If successfull it will return 0 otherwise it will return 1 */
/******************************************************************************/
struct hostent *hp;
struct sockaddr_in sin;
char buf[TCOB_MAX_PATHLN];
#ifndef __MINGW32__
int s;
#else
SOCKET s;
#endif
int command;
pid_t mypid;
#ifdef __MINGW32__
init_socket();
#endif
/* Translate host name into peer's IP address */
if ((hp = gethostbyname(lockserverhost)) == NULL) {
fprintf(stderr, "unknown host %s\n",lockserverhost);
exit(1);
}
/*
* Initialize the address data structure
*/
memset((void *)&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
memcpy((void *)&sin.sin_addr, hp->h_addr, hp->h_length);
sin.sin_port = htons(SERVER_PORT);
/*
* Create a socket
*/
if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
perror("socket");
exit(1);
}
/*
* Create a connection between the socket and the server
*/
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
perror("connect: Check that Lockserver is running");
exit(1);
}
/* Get Connection Result
*/;
recv(s, buf, 1, 0);
if(buf[0] < 1) {
perror("Access Denied: Check that your IP is defined in the hosts file");
exit(1);
}
// Set Command to Release a Specific lock
command=0x5;
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Length of Key
command=strlen(filename);
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Key
#ifndef __MINGW32__
write(s, filename, command);
#else
write_socket(s, filename, command);
#endif
//Length of Index
command=strlen(key);
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Index
#ifndef __MINGW32__
write(s, key, command);
#else
write_socket(s, key, command);
#endif
//Get My PID and use it as owner
mypid = getpid();
sprintf(buf,"%i",mypid);
//Length of Owner
command=strlen(buf);
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Owner
#ifndef __MINGW32__
write(s, buf,command);
#else
write_socket(s, buf,command);
#endif
//Get 2 Byte Int Response.
#ifndef __MINGE32__
read(s, &command, 1);
#else
read_socket(s, &command, 1);
#endif
command = command << 8;
#ifndef __MINGW32__
read(s, &command, 1);
#else
read_socket(s, &command, 1);
#endif
#ifndef __MINGW32__
close(s);
#else
closesocket(s);
WSACleanup();
#endif
if(command > 0)
{
return(0);
}
else
{
return(1);
}
}
/*------------------------------------------------------------------------*\
| |
| lockserver_release_all_locks |
| |
\*------------------------------------------------------------------------*/
int lockserver_release_all_locks()
{
/******************************************************************************/
/* This routine will connect to the Lockserver process and release all */
/* lock for the running program. */
/* If the record is successfull it will return 0 otherwise it will return 1 */
/******************************************************************************/
struct hostent *hp;
struct sockaddr_in sin;
char buf[TCOB_MAX_PATHLN];
#ifndef __MINGW32__
int s;
#else
SOCKET s;
#endif
int command;
pid_t mypid;
#ifdef __MINGW32__
init_socket();
#endif
/* Translate host name into peer's IP address */
if ((hp = gethostbyname(lockserverhost)) == NULL) {
fprintf(stderr, "unknown host %s\n",lockserverhost);
exit(1);
}
/*
* Initialize the address data structure
*/
memset((void *)&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
memcpy((void *)&sin.sin_addr, hp->h_addr, hp->h_length);
sin.sin_port = htons(SERVER_PORT);
/*
* Create a socket
*/
if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
perror("socket");
exit(1);
}
/*
* Create a connection between the socket and the server
*/
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
perror("connect: Check that Lockserver is running");
exit(1);
}
/* Get Connection Result
*/;
recv(s, buf, 1, 0);
if(buf[0] < 1) {
perror("Access Denied: Check that your IP is defined in the hosts file");
exit(1);
}
// Set Command to Release All locks
command=0x6;
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Get My PID and use it as owner
mypid = getpid();
sprintf(buf,"%i",mypid);
//Length of Owner
command=strlen(buf);
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Owner
#ifndef __MINGW32__
write(s, buf,command);
#else
write_socket(s, buf,command);
#endif
//Get 2 Byte Int Response.
#ifndef __MINGW32__
read(s, &command, 1);
#else
read_socket(s, &command, 1);
#endif
command = command << 8;
#ifndef __MINGW32__
read(s, &command, 1);
#else
read_socket(s, &command, 1);
#endif
#ifndef __MINGW32__
close(s);
#else
closesocket(s);
WSACleanup();
#endif
if(command > 0)
{
return(0);
}
else
{
return(1);
}
}
/*------------------------------------------------------------------------*\
| |
| show_lock |
| |
\*------------------------------------------------------------------------*/
int show_lock( char *filename, char *key, char *pidid, char *username)
{
/******************************************************************************/
/* This routine will connect to the Lockserver process and see if a record is */
/* locked for a given filename, ker pair. */
/* The filename should be the full name of the */
/* of the file ie /home/andrew/names.db. The Key should be the PRIMARY key in */
/* the Datafile and not an Alternate Key. */
/* This process will return the Process ID and the Username locking the record*/
/******************************************************************************/
struct hostent *hp;
struct sockaddr_in sin;
FILE *pt;
char buf[TCOB_MAX_PATHLN];
#ifndef __MINGW32__
int s;
#else
SOCKET s;
#endif
int command;
char *owner;
#ifdef __MINGW32__
init_socket();
#endif
/* Translate host name into peer's IP address */
if ((hp = gethostbyname(lockserverhost)) == NULL) {
fprintf(stderr, "unknown host %s\n",lockserverhost);
exit(1);
}
/*
* Initialize the address data structure
*/
memset((void *)&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
memcpy((void *)&sin.sin_addr, hp->h_addr, hp->h_length);
sin.sin_port = htons(SERVER_PORT);
/*
* Create a socket
*/
if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
perror("socket");
exit(1);
}
/*
* Create a connection between the socket and the server
*/
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
perror("connect: Check that Lockserver is running");
exit(1);
}
/* Get Connection Result
*/;
recv(s, buf, 1,0);
if(buf[0] < 1) {
perror("Access Denied: Check that your IP is defined in the hosts file");
exit(1);
}
// Set Command to Find a Lock Ownerk
command=0x1;
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Length of Key
realpath(filename,buf);
command=strlen(buf);
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Key
#ifndef __MINGW32__
write(s, buf, command);
#else
write_socket(s, buf, command);
#endif
//Length of Index
command=strlen(key);
#ifndef __MINGW32__
write(s, &command, 1);
#else
write_socket(s, &command, 1);
#endif
//Index
#ifndef __MINGW32__
write(s, key, command);
#else
write_socket(s, key, command);
#endif
//Get Owner
#ifndef __MINGW32__
read(s, &command, 1);
#else
read_socket(s, &command, 1);
#endif
owner = (char *) malloc (sizeof(char) * (command + 1));
#ifndef __MINGW32__
read(s, owner, command);
#else
read_socket(s, owner, command);
#endif
owner[command] = '\0';
#ifndef __MINGW32__
close(s);
#else
closesocket(s);
WSACleanup();
#endif
strcpy(pidid,owner);
#ifdef __MINGW32__
strcpy(username,"Not-Implemented");
#else
sprintf(buf,"ps --no-header u %s | cut -f1 -d ' '",owner);
pt=popen(buf,"r");
fgets(buf,TCOB_MAX_PATHLN,pt);
strncpy(username,buf,strlen(buf)-1);
fclose(pt);
#endif
free(owner);
return(0);
}
void insert_filename( int fdb , char *filename )
{
int i;
for(i=0;i<=NO_OF_FILES;i++){
if(name_info[i].fd == 0)
{
name_info[i].fd=fdb;
realpath(filename,name_info[i].filesname);
break;
}
}
}
char *fd_filename( int fdb )
{
int i;
for(i=0;i<=NO_OF_FILES;i++){
if(name_info[i].fd == fdb)
{
return(name_info[i].filesname);
break;
}
}
return("");
}
void remove_filename( int fdb )
{
int i;
for(i=0;i<=NO_OF_FILES;i++){
if(name_info[i].fd == 0)
{
name_info[i].fd=0;
strcpy(name_info[i].filesname," ");
break;
}
}
}
#endif