    /*********************************************************************\
    *  Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu)   *
    *                                                                     *
    *  You may copy or modify this file in any manner you wish, provided  *
    *  that this notice is always included, and that you hold the author  *
    *  harmless for any loss or damage resulting from the installation or *
    *  use of this software.                                              *
    \*********************************************************************/

#include "client_def.h"

#ifndef NOLOCKING
static char key_string[sizeof(KEY_PREFIX)+32];

static char code_str[] =
    "0123456789:_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

static make_key_string(server_addr,server_port)
    unsigned long  server_addr; 
    unsigned short server_port;
{
    unsigned long v1, v2;
    char *p;

    strcpy(key_string,KEY_PREFIX);
    for(p = key_string; *p; p++);
    v1 = server_addr;
    v2 = server_port;

    *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
    *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
    *p++ = code_str[v1 & 0x3f]; v1 >>= 6; v1 = v1 | (v2 << (32-3*6));
    *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
    *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
    *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
    *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
    *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
    *p   = 0;
}
#endif

/********************************************************************/
/******* For those systems that has flock function call *************/
/********************************************************************/
#ifdef USE_FLOCK

#include <sys/file.h>

int key_persists = 1;
static unsigned int lock_fd;
static unsigned short okey;

client_get_key()
{
    if(flock(lock_fd,LOCK_EX)           == -1) { perror("flock"); exit(1); }
    if(read(lock_fd,&okey,sizeof(okey)) == -1) { perror("readk"); exit(1); }
    if(lseek(lock_fd,0L,0)              == -1) { perror("seek"); exit(1); }
    return(okey);
}

client_put_key(key)
    unsigned short key;
{
    if(write(lock_fd,&key,sizeof(key)) == -1) { perror("write"); exit(1); }
    if(lseek(lock_fd,0L,0)             == -1) { perror("seek"); exit(1); }
    if(flock(lock_fd,LOCK_UN)          == -1) { perror("unflock"); exit(1); }
}

client_init_key(server_addr,server_port,key)
    unsigned long  server_addr; 
    unsigned short server_port;
    unsigned short key;
{
    unsigned long omask;
    okey = key;

    make_key_string(server_addr,server_port);

    omask = umask(0);
    lock_fd = open(key_string,O_RDWR|O_CREAT,0666);
    umask(omask);
}

#endif
/********************************************************************/
/******* For those systems that has lockf function call *************/
/********************************************************************/
#ifdef USE_LOCKF

#include <unistd.h>

int key_persists = 1;
static unsigned int lock_fd;
static unsigned short okey;

client_get_key()
{
    if(lockf(lock_fd,F_LOCK,sizeof(okey)) == -1) { perror("lockf"); exit(1); }
    if(read(lock_fd,&okey,sizeof(okey))   == -1) { perror("readlk"); exit(1); }
    if(lseek(lock_fd,0L,0)                == -1) { perror("seek"); exit(1); }
    return(okey);
}

client_put_key(key)
    unsigned short key;
{
    if(write(lock_fd,&key,sizeof(key))    == -1) { perror("write"); exit(1); }
    if(lseek(lock_fd,0L,0)                == -1) { perror("seek"); exit(1); }
    if(lockf(lock_fd,F_ULOCK,sizeof(key)) == -1) { perror("unlockf"); exit(1); }
}

client_init_key(server_addr,server_port,key)
    unsigned long  server_addr; 
    unsigned short server_port;
    unsigned short key;
{
    unsigned long omask;
    okey = key;

    make_key_string(server_addr,server_port);

    omask = umask(0);
    lock_fd = open(key_string,O_RDWR|O_CREAT,0666);
    umask(omask);
}

#endif
/********************************************************************/
/******* For those systems that has SysV shared memory + lockf ******/
/********************************************************************/
#ifdef USE_SHAREMEM_AND_LOCKF

#include <unistd.h>
#include <sys/ipc.h>
extern char *shmat();

int key_persists = 0;
static unsigned short *share_key;
static unsigned int lock_fd;

client_get_key()
{
    if(lockf(lock_fd,F_LOCK,2) == -1) { perror("lockf"); exit(1); }
    return(*share_key);
}

client_put_key(key)
    unsigned short key;
{
    *share_key = key;
    if(lockf(lock_fd,F_ULOCK,2) == -1) { perror("unlockf"); exit(1); }
}

client_init_key(server_addr,server_port,key)
    unsigned long  server_addr; 
    unsigned short server_port;
    unsigned short key;
{
    unsigned long omask;
    key_t lock_key;
    int   lock_shm;

    make_key_string(server_addr,server_port);

    omask = umask(0);
    lock_fd = open(key_string,O_RDWR|O_CREAT,0666);
    umask(omask);

    if((lock_key = ftok(key_string,3432)) == -1){ perror("ftok"); exit(1); }
    if((lock_shm = shmget(lock_key,sizeof(short),IPC_CREAT|0666)) == -1)
						{ perror("shmget"); exit(1); }
    if(!(share_key = (unsigned short *) shmat(lock_shm,(char*)0,0)))
						{ perror("shmat"); exit(1); }
}

#endif
/********************************************************************/
/******* For those who does not want to use locking *****************/
/********************************************************************/
#ifdef NOLOCKING

int key_persists = 0;
static unsigned short okey;

client_get_key()
{
    return(okey);
}

client_put_key(key)
    unsigned short key;
{
    okey = key;
}

client_init_key(server_addr,server_port,key)
    unsigned long  server_addr; 
    unsigned short server_port;
    unsigned short key;
{
    okey = key;
}

#endif
/********************************************************************/
/********************************************************************/
/********************************************************************/
