




























#include <stdio.h>
#include <sys/types.h>
#include <ndbm.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/file.h>
#if defined(MIPS) && (defined(ULTRIX) || defined(ULTRIX40))
#include <limits.h>
#endif /* MIPS && ULTRIX */
#include <sys/stat.h>
#include <sys/socket.h>

#include "sched.h"
#include "expr.h"
#include "manager.h"
#include "debug.h"

extern MACH_REC *MachineList;

extern char *strdup();
extern char *param();

/*
** Tuple for the priority database.  Key off of the network address.
*/
typedef struct stored_prio {
    struct in_addr net_addr;
    int prio;
} STORED_PRIO;

#define PRIORITIES_FILE "~condor/log/priorites" /* name of file */
#define PRIORITIES_FILE_FLAGS (O_RDWR|O_CREAT) /* umask for file creation */
#if defined(MIPS) && (defined(ULTRIX) || defined(ULTRIX40))
#define PRIORITIES_FILE_MODE (S_IRUSR|S_IWUSR) /* mode for file creation */
#else
#define PRIORITIES_FILE_MODE (S_IREAD|S_IWRITE)
#endif /* MIPS && ULTRIX */

DBM *PrioDB;
int StablePriosInited = FALSE;

/*
** Determine where priority database will be stored.  This should probably
** be moved to the config files.
*/
char *
prioDB_filename()
{
	char *logdir;
	char filename[BUFSIZ];

	logdir = param( "LOG" );

	sprintf(filename, "%s/priorities", logdir);

	return(strdup(filename));
}

/*
** Initialize the database to contain priorities.
*/
init_stable_prios()
{
	char *priorities_file;

	priorities_file = prioDB_filename();

    PrioDB = dbm_open(priorities_file, PRIORITIES_FILE_FLAGS, 
		      PRIORITIES_FILE_MODE);

	free(priorities_file);

	if(PrioDB == NULL) {
		dprintf(D_ALWAYS, "Couldn't open priority DB.\n");
		return;
	}

    StablePriosInited = TRUE;
}

/*
** Close the priorities DB.
*/
close_stable_prios()
{
    dbm_close(PrioDB);
}

/*
** Store a priority in the DB.
*/
store_prio(addr, prio)
struct in_addr *addr;
int prio;
{
    datum key;
    datum tuple;
    STORED_PRIO stored_prio;

    bcopy((char *)addr, (char *)&stored_prio.net_addr, sizeof(stored_prio));
    stored_prio.prio = prio;

    key.dptr = (char *)&stored_prio.net_addr;
    key.dsize = sizeof(stored_prio.net_addr);
    
    tuple.dptr = (char *)&stored_prio;
    tuple.dsize = sizeof(stored_prio);

    if( dbm_store(PrioDB, key, tuple, DBM_REPLACE) < 0 ) {
		dprintf(D_ALWAYS, "Couldn't store prio.\n");
    }
}

/*
** Retrieve a prio from the DB.  Return zero if it wasn't previously stored.
*/
int
retrieve_prio(addr)
struct in_addr *addr;
{
    STORED_PRIO *stored_prio_ptr;
    STORED_PRIO stored_prio;
    datum key;
    datum tuple;
	struct in_addr newaddr;

    key.dptr = (char *)addr;
    key.dsize = sizeof(struct in_addr);

    tuple = dbm_fetch(PrioDB, key);

	/*
	** If the machine hasn't been stored in the DB previously, create a
	** record for it and give it a priority of zero.
	*/
    if( tuple.dptr == NULL ) {
		store_prio(addr, 0);
		return(0);
    }

    stored_prio_ptr = (STORED_PRIO *)tuple.dptr;

    return(stored_prio_ptr->prio);
}

/*
** Return the name of a host given its address.  Return NULL if unknown.
*/
char *
gethostnamebyaddr(addr)
struct in_addr *addr;
{
	struct hostent *hp;

	hp = gethostbyaddr(addr, sizeof(struct in_addr), AF_INET);

	if(hp) {
		return(strdup(hp->h_name));
	}
	else {
		return(NULL);
	}
}

/*
** Store all priorities to the DB.
*/
store_prios()
{
	MACH_REC *ptr;

	ptr = MachineList->next;

	while(ptr->name) {
		store_prio(&ptr->net_addr, ptr->prio);

		ptr = ptr->next;
	}
}

