/* * 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