Newsgroups: comp.sources.unix
From: pleierc@informatik.tu-muenchen.de (Christoph Pleier)
Subject: v27i185: distributed-c-2.1 - Distributed C Development Environment, V2.1, Part11/18
References: <1.756634932.28500@gw.home.vix.com>
Sender: unix-sources-moderator@gw.home.vix.com
Approved: vixie@gw.home.vix.com

Submitted-By: pleierc@informatik.tu-muenchen.de (Christoph Pleier)
Posting-Number: Volume 27, Issue 185
Archive-Name: distributed-c-2.1/part11

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 11 (of 18)."
# Contents:  config/ReadSymbtab.c config/symb_system.c
#   dcadmin/Location.c dcadmin/main.c dclocate/BuildLists.c
# Wrapped by vixie@gw.home.vix.com on Thu Dec 23 00:12:03 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'config/ReadSymbtab.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'config/ReadSymbtab.c'\"
else
echo shar: Extracting \"'config/ReadSymbtab.c'\" \(16007 characters\)
sed "s/^X//" >'config/ReadSymbtab.c' <<'END_OF_FILE'
X/***************************************************************************
X *                                                                         *
X * @@@@  @@@ @@@@@ @@@@@ @@@@@ @@@ @@@@  @   @ @@@@@ @@@@@ @@@@       @@@  *
X * @   @  @  @       @   @   @  @  @   @ @   @   @   @     @   @     @   @ *
X * @   @  @  @@@@@   @   @@@@@  @  @@@@@ @   @   @   @@@@@ @   @     @     *
X * @   @  @      @   @   @ @    @  @   @ @   @   @   @     @   @     @   @ *
X * @@@@  @@@ @@@@@   @   @  @  @@@ @@@@  @@@@@   @   @@@@@ @@@@       @@@  *
X *                                                                         *
X *              A compiler for distributed programming with C              *
X *                                                                         *
X *                        R e a d S y m b t a b . c                        *
X *                                                                         *
X *                            Package : Configuration Files Parsers        *
X *                            Version : 1.0                                *
X *                       CreationDate : 02.03.92                           *
X *                         LastUpDate : 04.03.92                           *
X *                                                                         *
X *             All routines needed for loading a symbol table.             *
X *                                                                         *
X *               Copyright (C) 1992-1994 by Christoph Pleier               *
X *                          All rights reserved!                           *
X ***************************************************************************/
X
X/*
X * This file is part of the Distributed C Development Environment (DCDE).
X * DCDE is free software; you can redistribute it and/or modify
X * it under the terms written in the README-file. 
X * DCDE is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
X * See the file README for more details.
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X#include "cfgparsers.h"
X
X/******************************************************************************
X * get_symbtab_entry()                                                        *
X *                                                                            *
X * Searches the symbol table entry corresponding to 'name'. Displays an error *
X * and terminates if no matching symbol found.                                *
X *                                                                            *
X * Return values: pointer to found symbol table entry upon success /          *
X *                exit upon error                                             *
X ******************************************************************************/
Xstatic SYMBTABEL *
Xget_symbtab_entry(name)
Xchar *name;
X{
X    SYMBTABEL *symbol;
X
X    symbol = lookup_symbtabel(name);
X
X    if (symbol)
X	return(symbol);
X
X    fprintf(stderr, "Panic: symbol \"%s\" not found in symbol table!\n", name);
X    fprintf(stderr, "Terminating.\n");
X    exit(-1);
X} /* get_symbtab_entry */
X
X/******************************************************************************
X * ReadIDENTLIST()                                                            *
X *                                                                            *
X * Reads a IDENTLIST from file 'filep'.                                       *
X *                                                                            *
X * Return values: pointer to generated list upon success / NULL upon error    *
X ******************************************************************************/
XIDENTLIST *
XReadIDENTLIST(filep)
XFILE *filep;
X{
X    register IDENTLIST *idl, *idlfirst = NULL, *idllast;
X    int count;
X    char str[100];
X    SYMBTABEL *symbol;
X
X    fscanf(filep, "%d\n", &count);
X
X    while(count--) {
X	fscanf(filep, "%s\n", str);
X	symbol = get_symbtab_entry(str);
X
X        idl = (IDENTLIST *) Malloc(sizeof(IDENTLIST));
X	idl->symbol = symbol;
X	idl->next   = NULL;
X
X	if (!idlfirst)
X	    idlfirst = idllast = idl;
X	else {
X	    idllast->next = idl;
X	    idllast = idl;
X	}
X    }
X
X    return(idlfirst);
X} /* ReadIDENTLIST */
X
X/******************************************************************************
X * ReadACCFSINFO()                                                            *
X *                                                                            *
X * Reads a ACCFSINFO from file 'filep'.                                       *
X *                                                                            *
X * Return values: pointer to generated list upon success / NULL upon error    *
X ******************************************************************************/
XACCFSINFO *
XReadACCFSINFO(filep)
XFILE *filep;
X{
X    register ACCFSINFO *afs, *afsfirst = NULL, *afslast;
X    int count;
X    float time;
X    char str[100];
X    SYMBTABEL *symbol;
X
X    fscanf(filep, "%d\n", &count);
X
X    while(count--) {
X	fscanf(filep, "%s %f\n", str, &time);
X	symbol = get_symbtab_entry(str);
X
X	afs = (ACCFSINFO *) Malloc(sizeof(ACCFSINFO));
X	afs->filesystem = symbol;
X	afs->acc_time   = time;
X	afs->next       = NULL;
X
X	if (!afsfirst)
X	    afsfirst = afslast = afs;
X	else {
X	    afslast->next = afs;
X	    afslast = afs;
X	}
X    }
X
X    return(afsfirst);
X} /* ReadACCFSINFO */
X
X/******************************************************************************
X * ReadFSSPECINFO()                                                           *
X *                                                                            *
X * Reads a FSSPECINFO from file 'filep'.                                      *
X *                                                                            *
X * Return values: pointer to generated list upon success / NULL upon error    *
X ******************************************************************************/
XFSSPECINFO *
XReadFSSPECINFO(filep)
XFILE *filep;
X{
X    register FSSPECINFO *fssp, *fsspfirst = NULL, *fssplast;
X    int count;
X    float freq, quant;
X    char str[100];
X    SYMBTABEL *symbol;
X
X    fscanf(filep, "%d\n", &count);
X
X    while(count--) {
X	fscanf(filep, "%s %f %f\n", str, &freq, &quant);
X	symbol = get_symbtab_entry(str);
X
X	fssp = (FSSPECINFO *) Malloc(sizeof(FSSPECINFO));
X	fssp->filesys   = symbol;
X	fssp->frequency = freq;
X	fssp->quantity  = quant;
X	fssp->next      = NULL;
X
X	if (!fsspfirst)
X	    fsspfirst = fssplast = fssp;
X	else {
X	    fssplast->next = fssp;
X	    fssplast = fssp;
X	}
X    }
X
X    return(fsspfirst);
X} /* ReadFSSPECINFO */
X
X/******************************************************************************
X * ReadCOMMPINFO()                                                            *
X *                                                                            *
X * Reads a COMMPINFO from file 'filep'.                                       *
X *                                                                            *
X * Return values: pointer to generated list upon success / NULL upon error    *
X ******************************************************************************/
XCOMMPINFO *
XReadCOMMPINFO(filep)
XFILE *filep;
X{
X    register COMMPINFO *commp, *commpfirst = NULL, *commplast;
X    int count;
X    float freq, quant;
X    char str[100];
X    SYMBTABEL *symbol;
X
X    fscanf(filep, "%d\n", &count);
X
X    while(count--) {
X	fscanf(filep, "%s %f %f\n", str, &freq, &quant);
X	symbol = get_symbtab_entry(str);
X
X	commp = (COMMPINFO *) Malloc(sizeof(COMMPINFO));
X	commp->Process   = symbol;
X	commp->frequency = freq;
X	commp->quantity  = quant;
X	commp->next      = NULL;
X
X	if (!commpfirst)
X	    commpfirst = commplast = commp;
X	else {
X	    commplast->next = commp;
X	    commplast = commp;
X	}
X    }
X
X    return(commpfirst);
X} /* ReadCOMMPINFO */
X
X/******************************************************************************
X * ReadPATTRINFO()                                                            *
X *                                                                            *
X * Reads a PATTRINFO from file 'filep'.                                       *
X *                                                                            *
X * Return values: pointer to generated list upon success / NULL upon error    *
X ******************************************************************************/
XPATTRINFO *
XReadPATTRINFO(filep)
XFILE *filep;
X{
X    register PATTRINFO *pattr, *pattrfirst = NULL, *pattrlast;
X    int count, type;
X
X    fscanf(filep, "%d\n", &count);
X
X    while(count--) {
X	pattr = (PATTRINFO *) Malloc(sizeof(PATTRINFO));
X	fscanf(filep, "%d\n", &type); 
X	pattr->type = type;
X	switch(type) {
X	case PA_PHYS_MEM:
X            fscanf(filep, "%d %f\n",
X                &(pattr->mode),
X                &(pattr->info.phys_mem_size));
X            break;
X        case PA_VIRT_MEM:
X            fscanf(filep, "%d %f\n",
X                &(pattr->mode),
X                &(pattr->info.virt_mem_size));
X            break;
X        case PA_VECTORIZATION:
X            fscanf(filep, "%d\n", &(pattr->mode));
X            break;
X        case PA_PARALLELIZATION:
X            fscanf(filep, "%d\n", &(pattr->mode));
X            break;
X	} /* switch */
X	if (!pattrfirst)
X	    pattrfirst = pattrlast = pattr;
X	else {
X	    pattrlast->next = pattr;
X	    pattrlast = pattr;
X	}
X    }
X
X    return(pattrfirst);
X} /* ReadPATTRINFO */
X
X/******************************************************************************
X * ReadPHOSTLIST()                                                            *
X *                                                                            *
X * Reads a PHOSTLIST from file 'filep'.                                       *
X *                                                                            *
X * Return values: pointer to generated list upon success / NULL upon error    *
X ******************************************************************************/
XPHOSTLIST *
XReadPHOSTLIST(filep)
XFILE *filep;
X{
X    register PHOSTLIST *phost, *phostfirst = NULL, *phostlast;
X    int count, preferred, wished_val;
X    float load, overall;
X    char str[100];
X    SYMBTABEL *symbol;
X
X    fscanf(filep, "%d\n", &count);
X
X    while(count--) {
X        fscanf(filep, "%s %d %d %f %f\n", str, &preferred, &wished_val, &load, &overall);
X	symbol = get_symbtab_entry(str);
X
X	phost = (PHOSTLIST *) Malloc(sizeof(PHOSTLIST));
X	phost->Host          = symbol;
X	phost->preferred     = preferred;
X	phost->wished_val    = wished_val;
X	phost->load          = load;
X	phost->overall_index = overall;
X
X	if (!phostfirst)
X	    phostfirst = phostlast = phost;
X	else {
X	    phostlast->next = phost;
X	    phostlast = phost;
X	}
X    }
X
X    return(phostfirst);
X} /* ReadPHOSTLIST */
X
X/******************************************************************************
X * ReadCOSTINFO()                                                             *
X *                                                                            *
X * Reads a COSTINFO from file 'filep'.                                        *
X *                                                                            *
X * Return values: pointer to generated list upon success / NULL upon error    *
X ******************************************************************************/
XCOSTINFO *
XReadCOSTINFO(filep)
XFILE *filep;
X{
X    register COSTINFO *costl, *costlfirst = NULL, *costllast;
X    int count;
X    char str[100];
X    SYMBTABEL *symbol;
X
X    fscanf(filep, "%d\n", &count);
X
X    while(count--) {
X	costl = (COSTINFO *) Malloc(sizeof(COSTINFO));
X        fscanf(filep, "%s %f %f\n", str, &(costl->crea_val), &(costl->comm_val));
X	costl->dest_host = get_symbtab_entry(str);
X
X	if (!costlfirst)
X	    costlfirst = costllast = costl;
X	else {
X	    costllast->next = costl;
X	    costllast = costl;
X	}
X    }
X
X    return(costlfirst);
X} /* ReadCOSTINFO */
X
X/******************************************************************************
X * ReadSYMBTABEL()                                                            *
X *                                                                            *
X * Reads a SYMBTABEL from file 'filep'                                        *
X *                                                                            *
X * Return values: pointer to read element upon success / NULL upon error      *
X ******************************************************************************/
XSYMBTABEL *
XReadSYMBTABEL(filep, symbol)
XFILE *filep;
XSYMBTABEL *symbol;
X{
X    char str1[100], str2[100], str3[100];
X    int i1, i2, i3, i4, i5;
X
X    switch(symbol->type) {
X    case UNDEFINED:
X	break;
X    case S_HOST:
X	fscanf(filep, "%s %s %f %f %f %d %d %d %d %d %s\n", 
X	    str1, str2, 
X	    &(symbol->info.Host.phys_mem), 
X	    &(symbol->info.Host.virt_mem),
X	    &(symbol->info.Host.perf_index), 
X	    &i1, &i2, &i3, &i4, &i5, str3);
X	symbol->info.Host.os                 = get_symbtab_entry(str1);
X	symbol->info.Host.type               = get_symbtab_entry(str2);
X	symbol->info.Host.multiprocessor     = (short) i1;
X        symbol->info.Host.processors         = (short) i2;
X	symbol->info.Host.memory_type        = (short) i3;
X	symbol->info.Host.has_par_compiler   = (short) i4;
X	symbol->info.Host.is_vector_computer = (short) i5;
X	symbol->info.Host.ex_storage         = get_symbtab_entry(str3);
X	symbol->info.Host.p_devices          = ReadIDENTLIST(filep);
X        symbol->info.Host.f_systems          = ReadACCFSINFO(filep);
X        symbol->info.Host.costinfo           = ReadCOSTINFO(filep);
X        symbol->info.Host.compinfo           = NULL;
X        symbol->info.Host.prob_load          = 0;
X        symbol->info.Host.pcreated           = 0;
X	break;
X    case S_COMPUTER_TYPE:
X    case S_OPERATING_SYSTEM:
X	break;
X    case S_FIXED_DISK:
X	fscanf(filep, "%s %f %f\n", 
X	    str1, &(symbol->info.disk.size), &(symbol->info.disk.speed));
X	symbol->info.disk.location = get_symbtab_entry(str1);
X	break;
X    case S_PROCESS:
X	fscanf(filep, "%f\n", &(symbol->info.Process.intensity_index));
X	symbol->info.Process.pref_hosts  = ReadIDENTLIST(filep);
X        symbol->info.Process.rest_hosts  = ReadIDENTLIST(filep);
X        symbol->info.Process.peri_dev    = ReadIDENTLIST(filep);
X        symbol->info.Process.filesystems = ReadFSSPECINFO(filep);
X        symbol->info.Process.commps      = ReadCOMMPINFO(filep);
X        symbol->info.Process.others      = ReadPATTRINFO(filep);
X        symbol->info.Process.phostlist   = ReadPHOSTLIST(filep);
X	break;
X    default:
X	fprintf(stderr, "Panic: unknown symbol table entry found in ReadSYMBTABEL()\n");
X        fprintf(stderr, "Symbol name is \"%s\". Terminating.\n", symbol->name);
X        exit(-1);
X    } /* switch */
X
X    return(symbol);
X} /* ReadSYMBTABEL */
X
X/******************************************************************************
X * ReadSymbtab()                                                              *
X *                                                                            *
X * Reads a complete symbol table from file 'filename'.                        *
X *                                                                            *
X * Return values: OK upon success / ERROR upon error                          *
X ******************************************************************************/
Xint
XReadSymbtab(filep)
XFILE *filep;
X{
X    int count, count2, type;
X    SYMBTABEL *symbol;
X    char str[100];
X
X    fscanf(filep, "%d\n", &count);
X    count2 = count;
X
X    while(count--) {
X        fscanf(filep, "%s %d\n", str, &type);
X	symbol = enter_symbtabel(str);
X	symbol->type = type;
X    }
X
X    while(count2--) {
X        fscanf(filep, "%s %d\n", str, &type);
X	symbol = get_symbtab_entry(str);
X	if (symbol->type != type) {
X            fprintf(stderr,"Panic: wrong symbol type found. Terminating.\n");
X            return(ERROR);
X	}
X	ReadSYMBTABEL(filep, symbol);
X    }
X    return(OK);
X} /* ReadSymbtab */
END_OF_FILE
if test 16007 -ne `wc -c <'config/ReadSymbtab.c'`; then
    echo shar: \"'config/ReadSymbtab.c'\" unpacked with wrong size!
fi
# end of 'config/ReadSymbtab.c'
fi
if test -f 'config/symb_system.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'config/symb_system.c'\"
else
echo shar: Extracting \"'config/symb_system.c'\" \(16203 characters\)
sed "s/^X//" >'config/symb_system.c' <<'END_OF_FILE'
X/***************************************************************************
X *                                                                         *
X * @@@@  @@@ @@@@@ @@@@@ @@@@@ @@@ @@@@  @   @ @@@@@ @@@@@ @@@@       @@@  *
X * @   @  @  @       @   @   @  @  @   @ @   @   @   @     @   @     @   @ *
X * @   @  @  @@@@@   @   @@@@@  @  @@@@@ @   @   @   @@@@@ @   @     @     *
X * @   @  @      @   @   @ @    @  @   @ @   @   @   @     @   @     @   @ *
X * @@@@  @@@ @@@@@   @   @  @  @@@ @@@@  @@@@@   @   @@@@@ @@@@       @@@  *
X *                                                                         *
X *              A compiler for distributed programming with C              *
X *                                                                         *
X *                        s y m b _ s y s t e m . c                        *
X *                                                                         *
X *                            Package : Configuration Files Parsers        *
X *                            Version : 1.0                                *
X *                       CreationDate : 26.02.92                           *
X *                         LastUpDate : 26.02.92                           *
X *                                                                         *
X * All routines needed to manage the symbol table during parsing of system *
X * configuration files.                                                    *
X *                                                                         *
X *               Copyright (C) 1992-1994 by Christoph Pleier               *
X *                          All rights reserved!                           *
X ***************************************************************************/
X
X/*
X * This file is part of the Distributed C Development Environment (DCDE).
X * DCDE is free software; you can redistribute it and/or modify
X * it under the terms written in the README-file. 
X * DCDE is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
X * See the file README for more details.
X */
X
X#include <stdio.h>
X#include "cfgparsers.h"
X
X/******************************************************************************
X * enter_disk_definition()                                                    *
X *                                                                            *
X * Enters the disk definition 'symbol' in the symbol table including all      *
X * informations.                                                              *
X *                                                                            *
X * Return values: pointer to entered element upon success / NULL upon error   *
X ******************************************************************************/
XSYMBTABEL *
Xenter_disk_definition(symbol, location, size, speed)
XSYMBTABEL *symbol, *location;
Xfloat size, speed;
X{
X    /* check symbol */
X    if (symbol->type != UNDEFINED) {
X	printf("Error: line %d at \"%s\": redefinition: \"%s\"\n",
X	    yylineno, yytext, symbol->name);
X	return(NULL);
X    }
X
X    symbol->type = S_FIXED_DISK;
X    symbol->info.disk.location    = location;
X    symbol->info.disk.size        = size;
X    symbol->info.disk.speed       = speed;
X    symbol->info.disk.wasprepared = FALSE;
X    symbol->info.disk.wascleaned  = FALSE;
X
X    return(symbol);
X} /* enter_disk_definition */
X
X/******************************************************************************
X * enter_host_specification()                                                 *
X *                                                                            *
X * Enters the host definitions specified by 'idents' in the symbol table      *
X * including all informations.                                                *
X *                                                                            *
X * Return values: pointer to first element upon success / NULL upon error     *
X ******************************************************************************/
XSYMBTABEL *
Xenter_host_specification(idents, os_def, compu_spec, p_def, compi_spec, files_def)
XIDENTLIST *idents;
XSYMBTABEL *os_def;
XCOMPSPEINFO *compu_spec;
XIDENTLIST *p_def;
XTARGETINFO *compi_spec;
XACCFSINFO *files_def;
X{
X    register IDENTLIST *idl;
X    SYMBTABEL *symbol;
X
X    for(idl = idents; idl; idl = idl->next) {
X
X	symbol = idl->symbol;
X
X	/* check symbol */
X        if (symbol->type != S_HOST) {
X	    printf("Error: line %d at \"%s\": \"%s\" is not a host name\n",
X	        yylineno, yytext, symbol->name);
X	    exit(ERROR);
X        }
X
X	symbol->info.Host.os                 = os_def;
X	symbol->info.Host.type               = compu_spec->type;
X	symbol->info.Host.phys_mem           = compu_spec->phys_mem;
X	symbol->info.Host.virt_mem           = compu_spec->virt_mem;
X	symbol->info.Host.perf_index         = compu_spec->perf_index;
X	symbol->info.Host.multiprocessor     = compu_spec->multiprocessor;
X	symbol->info.Host.processors         = compu_spec->processors;
X	symbol->info.Host.memory_type        = compu_spec->memory_type;
X	symbol->info.Host.has_par_compiler   = compu_spec->has_par_compiler;
X	symbol->info.Host.is_vector_computer = compu_spec->is_vector_computer;
X	symbol->info.Host.p_devices          = p_def;
X	symbol->info.Host.f_systems          = files_def;
X	symbol->info.Host.compinfo           = compi_spec;
X	symbol->info.Host.ex_storage         = compu_spec->ex_storage;
X	symbol->info.Host.istarget           = FALSE;
X	symbol->info.Host.wasmade            = FALSE;
X	symbol->info.Host.costinfo           = NULL;
X	symbol->info.Host.prob_load          = 0.0;
X	symbol->info.Host.pcreated           = 0;
X
X    }
X
X    Free((char *) compu_spec);
X
X    return(idents->symbol);
X} /* enter_host_specification */
X
X/******************************************************************************
X * enter_cost_definition()                                                    *
X *                                                                            *
X * Enters a cost definition in the symbol table.                              *
X *                                                                            *
X * Return values: pointer to entered element upon success / NULL upon error   *
X ******************************************************************************/
XSYMBTABEL *
Xenter_cost_definition(src_symb, dest_symb, crea_val, comm_val)
XSYMBTABEL *src_symb, *dest_symb;
Xfloat crea_val, comm_val;
X{
X    COSTINFO *ptr;
X
X    /* check symbols */
X    if (src_symb->type != S_HOST) {
X	printf("Error: line %d at \"%s\": symbol \"%s\" not defined as host\n",
X	    yylineno, yytext, src_symb->name);
X	return(NULL);
X    }
X    if (dest_symb->type != S_HOST) {
X	printf("Error: line %d at \"%s\": symbol \"%s\" not defined as host\n",
X	    yylineno, yytext, dest_symb->name);
X	return(NULL);
X    }
X
X    ptr = (COSTINFO *) Malloc(sizeof(COSTINFO));
X    ptr->dest_host = dest_symb;
X    ptr->crea_val  = crea_val;
X    ptr->comm_val  = comm_val;
X    ptr->next      = src_symb->info.Host.costinfo;
X    src_symb->info.Host.costinfo = ptr;
X
X    return(src_symb);
X} /* enter_cost_definition */
X
X/******************************************************************************
X * generate_targetinfo()                                                      *
X *                                                                            *
X * Generates and initializes a target information element.                    *
X *                                                                            *
X * Return values: pointer to new element upon success / NULL upon error       *
X ******************************************************************************/
XTARGETINFO *
Xgenerate_targetinfo(type, os, cc, cflags, ldflags, libs)
XSYMBTABEL *type, *os;
Xchar *cc, *cflags, *ldflags, *libs;
X{
X    register TARGETINFO *ptr;
X
X    /* check type */
X    if (type->type != S_COMPUTER_TYPE) {
X	printf("Error: line %d at \"%s\": \"%s\" is not a computer type\n",
X	    yylineno, yytext, type->name);
X	exit(ERROR);
X    }
X
X    /* check os */
X    if (os->type != S_OPERATING_SYSTEM) {
X	printf("Error: line %d at \"%s\": \"%s\" is not an operating system\n",
X	    yylineno, yytext, type->name);
X	exit(ERROR);
X    }
X
X    ptr = (TARGETINFO *) Malloc(sizeof(TARGETINFO));
X    ptr->type      = type->name;
X    ptr->os        = os->name;
X    ptr->cc        = cc;
X    ptr->cflags    = cflags;
X    ptr->ldflags   = ldflags;
X    ptr->libs      = libs;
X    ptr->next      = NULL;
X    return(ptr);
X} /* generate_targetinfo */
X
X/******************************************************************************
X * chain_targetinfos()                                                        *
X *                                                                            *
X * Chains targetinfo 't2' to the end of targetinfo 't1'.                      *
X *                                                                            *
X * Return values: pointer to resulting targetinfo upon success /              *
X *                NULL upon error                                             *
X ******************************************************************************/
XTARGETINFO *
Xchain_targetinfos(t1, t2)
XTARGETINFO *t1, *t2;
X{
X    register TARGETINFO *ptr;
X
X    for(ptr = t1; ptr->next; ptr = ptr->next)
X	;
X    ptr->next = t2;
X    return(t1);
X} /* chain_targetinfos */
X
X/******************************************************************************
X * generate_accfs_info()                                                      *
X *                                                                            *
X * Generates and initializes a accessible filesystem info.                    *
X *                                                                            *
X * Return values: pointer to new element upon success / NULL upon error       *
X ******************************************************************************/
XACCFSINFO *
Xgenerate_accfs_info(fs_symbol, acc_time)
XSYMBTABEL *fs_symbol;
Xfloat acc_time;
X{
X    register ACCFSINFO *ptr;
X
X    /* check type */
X    if (fs_symbol->type != S_FIXED_DISK) {
X	printf("Error: line %d at \"%s\": \"%s\" is not a fixed disk\n",
X	    yylineno, yytext, fs_symbol->name);
X	exit(ERROR);
X    }
X
X    ptr = (ACCFSINFO *) Malloc(sizeof(ACCFSINFO));
X    ptr->filesystem = fs_symbol;
X    ptr->acc_time   = acc_time;
X    ptr->next       = NULL;
X
X    return(ptr);
X} /* generate_accfs_info */
X
X/******************************************************************************
X * chain_accfs_infos()                                                        *
X *                                                                            *
X * Chains accessible filesystems info 'accfs2' to the end of info 'accfs1'.   *
X *                                                                            *
X * Return values: pointer to resulting targetinfo upon success /              *
X *                NULL upon error                                             *
X ******************************************************************************/
XACCFSINFO *
Xchain_accfs_infos(accfs1, accfs2)
XACCFSINFO *accfs1, *accfs2;
X{
X    register ACCFSINFO *ptr;
X
X    for(ptr = accfs1; ptr->next; ptr = ptr->next)
X	;
X    ptr->next = accfs2;
X    return(accfs1);
X} /* chain_accfs_infos */
X
X/******************************************************************************
X * generate_multi_info()                                                      *
X *                                                                            *
X * Generates and initializes the multiprocessor_specification_info.           *
X *                                                                            *
X * Return values: pointer to new created element upon success /               *
X *                NULL upon error                                             *
X ******************************************************************************/
XMULTIINFO *
Xgenerate_multi_info(proc_num, mem_type)
Xfloat proc_num;
Xshort mem_type;
X{
X    MULTIINFO *ptr;
X
X    ptr = (MULTIINFO *) Malloc(sizeof(MULTIINFO));
X
X    ptr->proc_num = (short) proc_num;
X    ptr->mem_type = mem_type;
X
X    return(ptr);
X} /* generate_multi_info */
X
X/******************************************************************************
X * generate_opt_comp_attr_info()                                              *
X *                                                                            *
X * Generates and initializes the optional_computer_attribute_info.            *
X *                                                                            *
X * Return values: pointer to new created element upon success /               *
X *                NULL upon error                                             *
X ******************************************************************************/
XOPTCOMPINFO *
Xgenerate_opt_comp_attr_info(multiinfo, attr)
XMULTIINFO *multiinfo;
Xshort attr;
X{
X    OPTCOMPINFO *ptr;
X
X    ptr = (OPTCOMPINFO *) Malloc(sizeof(OPTCOMPINFO));
X    ptr->multiinfo    = NULL;
X    ptr->is_vector    = FALSE;
X    ptr->has_par_comp = FALSE;
X
X    if (multiinfo)
X        ptr->multiinfo = multiinfo;
X    else {
X	switch(attr) {
X	case VECTOR_COMPUTER:
X    	    ptr->is_vector = TRUE;
X	    break;
X	case PAR_COMPILER:
X    	    ptr->has_par_comp = TRUE;
X	    break;
X	} /* switch */
X    }
X
X    return(ptr);
X} /* generate_opt_comp_attr_info */
X
X/******************************************************************************
X * add_opt_comp_attr_info()                                                   *
X *                                                                            *
X * Adds the optional_computer_attribute_list_info of attr2 to attr1.          *
X *                                                                            *
X * Return values: pointer to new created element upon success /               *
X *                NULL upon error                                             *
X ******************************************************************************/
XOPTCOMPINFO *
Xadd_opt_comp_attr_info(attr1, attr2)
XOPTCOMPINFO *attr1, *attr2;
X{
X    if (attr2->multiinfo)
X        attr1->multiinfo = attr2->multiinfo;
X    if (attr2->is_vector)
X        attr1->is_vector = TRUE;
X    if (attr2->has_par_comp)
X        attr1->has_par_comp = TRUE;
X
X    return(attr1);
X} /* add_opt_comp_attr_info */
X
X/******************************************************************************
X * generate_comp_spec_info()                                                  *
X *                                                                            *
X * Generates and initializes the computer_specification_info.                 *
X *                                                                            *
X * Return values: pointer to new created element upon success /               *
X *                NULL upon error                                             *
X ******************************************************************************/
XCOMPSPEINFO *
Xgenerate_comp_spec_info(type, p_mem, v_mem, perf, opt_attrs, store)
XSYMBTABEL *type, *store;
Xfloat p_mem, v_mem, perf;
XOPTCOMPINFO *opt_attrs;
X
X{
X    COMPSPEINFO *ptr;
X
X    ptr = (COMPSPEINFO *) Malloc(sizeof(COMPSPEINFO));
X
X    ptr->type               = type;
X    ptr->phys_mem           = p_mem;
X    ptr->virt_mem           = v_mem;
X    ptr->perf_index         = perf;
X    if (opt_attrs) {
X	if (opt_attrs->multiinfo) {
X            ptr->multiprocessor = TRUE;
X            ptr->processors     = opt_attrs->multiinfo->proc_num;
X            ptr->memory_type    = opt_attrs->multiinfo->mem_type;
X        }
X        ptr->has_par_compiler   = opt_attrs->has_par_comp;
X        ptr->is_vector_computer = opt_attrs->is_vector;
X    } else {
X        ptr->multiprocessor     = FALSE;
X        ptr->processors         = 1;
X        ptr->memory_type        = SHARED_MEMORY;
X        ptr->has_par_compiler   = FALSE;
X        ptr->is_vector_computer = FALSE;
X    }
X    ptr->ex_storage         = store;
X
X    Free((char *) opt_attrs);
X
X    return(ptr);
X} /* generate_comp_spec_info */
X
END_OF_FILE
if test 16203 -ne `wc -c <'config/symb_system.c'`; then
    echo shar: \"'config/symb_system.c'\" unpacked with wrong size!
fi
# end of 'config/symb_system.c'
fi
if test -f 'dcadmin/Location.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dcadmin/Location.c'\"
else
echo shar: Extracting \"'dcadmin/Location.c'\" \(15073 characters\)
sed "s/^X//" >'dcadmin/Location.c' <<'END_OF_FILE'
X/***************************************************************************
X *                                                                         *
X * @@@@  @@@ @@@@@ @@@@@ @@@@@ @@@ @@@@  @   @ @@@@@ @@@@@ @@@@       @@@  *
X * @   @  @  @       @   @   @  @  @   @ @   @   @   @     @   @     @   @ *
X * @   @  @  @@@@@   @   @@@@@  @  @@@@@ @   @   @   @@@@@ @   @     @     *
X * @   @  @      @   @   @ @    @  @   @ @   @   @   @     @   @     @   @ *
X * @@@@  @@@ @@@@@   @   @  @  @@@ @@@@  @@@@@   @   @@@@@ @@@@       @@@  *
X *                                                                         *
X *              A compiler for distributed programming with C              *
X *                                                                         *
X *                           L o c a t i o n . c                           *
X *                                                                         *
X *                            Package : Administration Process             *
X *                            Version : 1.0                                *
X *                       CreationDate : 16.09.90                           *
X *                         LastUpDate : 14.04.92                           *
X *                                                                         *
X * The routine 'DetermineCreationLocation' which determines the location   *
X * where to create processes which creation location was not specified     *
X * in the Distributed C program.                                           *
X *                                                                         *
X *               Copyright (C) 1990-1994 by Christoph Pleier               *
X *                          All rights reserved!                           *
X ***************************************************************************/
X
X/*
X * This file is part of the Distributed C Development Environment (DCDE).
X * DCDE is free software; you can redistribute it and/or modify
X * it under the terms written in the README-file. 
X * DCDE is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
X * See the file README for more details.
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <string.h>
X#ifdef HETEROGENEOUS
X# include <rpc/rpc.h>
X#endif
X#include <errno.h>
X#include "ipc.h"
X#include "dcc.h"
X#include "run_Errno.h"
X#include "timeout.h"
X#include "dcadmin.h"
X#ifndef USE_MAPFILE
X# include "cfgparsers.h"
X#endif /* USE_MAPFILE /**/
X#include "location.h"
X
X#ifdef ADMINDEBUG
X# define DEBUGPUTS(str)		fprintf(dfile,"[dbg] %s %s\n", _processprefix, str)
X# define DEBUGFPRINTF(f, a)	fprintf(dfile, f, a)
X#else
X# define DEBUGPUTS(str)		/* nothing */
X# define DEBUGFPRINTF(f, a)	/* nothing */
X#endif /* ADMINDEBUG /**/
X
X#define EXIT(v)			fprintf(stderr, "dcadmin: Terminating!\n"); \
X				exit(v)
X
X/******************************************************************************
X * DetermineCreationLocation()                                                *
X *                                                                            *
X * Determines the location where to create a specific process.                *
X *                                                                            *
X * Return values: OK upon success / ERROR upon error                          *
X ******************************************************************************/
Xint
XDetermineCreationLocation()
X{
X    char *pname,		/* name of process */
X         *pfilename,		/* corresponding file name */
X         *clocation,		/* location of creator process */
X         inputname[100],
X	 creat_loc[100];
X    ADMINLOCINFO locinfo;
X#ifdef USE_MAPFILE
X    struct pcreat_list *ptr, *res_ptr, *min_ptr;
X#else 
X    char *result;
X    float h1, h2, h3, h4, h5, h6;
X    PHOSTLIST *phostp, *phostl;
X    COSTINFO *costl, *costl2;
X    COMMPINFO *coml;
X    SYMBTABEL *act_host, *psymbol, *crea_symb, *hsymbol;
X    struct pdat_list *pdatl;
X    float best_index, dcadmin_index, oload_val, crea_val, ipc_val;
X#endif /* USE_MAPFILE /**/
X    struct pdat_list *pdatptr;
X
X    if (check_allocation) {
X	fprintf(stderr, "Enter name of process to allocate: ");
X	scanf("%s", inputname);
X	pname = &(inputname[0]);
X	if (!strcmp(pname, "done"))
X	    return(0);
X	pfilename = "(unknown)";
X    } else {
X        /* receive processname */
X#if defined(SINGLE) || defined(HOMOGENEOUS)
X        if (_recv_data(&_con_port, (char *) &locinfo, sizeof(ADMINLOCINFO), ADMINPRCTIME) < 0) {
X#else /* HETEROGENEOUS */
X        if (_recv_data_encoded(&_con_port, (char *) &locinfo, xdr_ADMINLOCINFO, ADMINPRCTIME)) {
X#endif /* SINGLE || HOMOGENEOUS /**/
X	    if (Errno == ETIMEOUT)
X	        Errno = ETCADRCVNAME;
X	    error("determining creation location");
X	    EXIT(ERROR);
X        }
X        pname     = locinfo.processname;
X        pfilename = locinfo.processfilename;
X	clocation = locinfo.creator_location;
X    }
X#ifdef ADMINDEBUG
X    fprintf(dfile, "[dbg] %s DETERMINING location to create process \"%s\" (\"%s\")\n",
X	_processprefix, pname, (pfilename) ? pfilename : "???");
X    if (_debugflush)
X	fflush(dfile);
X#endif /* ADMINDEBUG /**/
X
X#ifdef USE_MAPFILE
X    /* Determine the location where to create the process with name 'pname'.
X     * We use the informations stored in the 'process creation list' to 
X     * determine, where to create the new process. These informations were
X     * read from a mapping file. The rules for choosing hosts are the 
X     * following:
X     *   1) If the list is empty the result is 'local'. Otherwise
X     *   2) Search the list for entries matching the processname: 
X     *      a) If there is an entry with a 'num' specification and the number 
X     *         of the created processes is less than num take this entry as 
X     *         result (CASE 1a). Otherwise
X     *      b) If there are one ore more entries without a 'num' specification,
X     *         take the entry with the minimal number of already created 
X     *         processes (CASE 1b). Otherwise
X     *   3) Search the list for entries without processname specification:
X     *      a) If there is an entry with a 'num' specification and the number 
X     *         of the created processes is less than num take this entry as 
X     *         result (CASE 2a). Otherwise
X     *      b) If there are one ore more entries without a 'num' specification,
X     *         take the entry with the minimal number of already created 
X     *         processes (CASE 2b). Otherwise
X     *   4) The result is 'local'.
X     */
X    res_ptr = min_ptr = NULL;
X    if (pcreat_first) {
X	/* CASE 1: entries matching the processname: 
X	 *	   syntax: [num] processname at [username@]hostname
X	 */
X        for(ptr = pcreat_first; ptr; ptr = ptr->next) {
X	    if (ptr->processname == NULL || strcmp(pname, ptr->processname)) 
X		continue;
X	    if (ptr->max_num != -1) {
X		/* CASE 1a: num specified: 
X		 *          syntax: num processname at [username@]hostname
X		 */
X		if (ptr->max_num > ptr->created_num) {
X		    res_ptr = ptr;
X		    break;
X		}
X	    } else {
X		/* CASE 1b: no num specified: 
X		 *          syntax: processname at [username@]hostname
X		 */
X		if (min_ptr == NULL || min_ptr->created_num > ptr->created_num)
X			    min_ptr = ptr;
X	    }
X	} /* for */
X	if (res_ptr == NULL)
X	    res_ptr = min_ptr;
X	if (res_ptr == NULL) {
X	    /* CASE 2: entries without processname: 
X	     *         syntax: [num at] [username@]hostname
X	     */
X            for(ptr = pcreat_first; ptr; ptr = ptr->next) {
X	        if (ptr->processname != NULL) 
X		    continue;
X	        if (ptr->max_num != -1) {
X		    /* CASE 2a: num specified: 
X		     *          syntax: num at [username@]hostname
X		     */
X		    if (ptr->max_num > ptr->created_num) {
X		        res_ptr = ptr;
X		        break;
X		    }
X	        } else {
X		    /* CASE 2b: no num specified: 
X		     *          syntax: [username@]hostname
X		     */
X		    if (min_ptr == NULL || min_ptr->created_num > ptr->created_num)
X			    min_ptr = ptr;
X	        }
X	    } /* for */
X	    if (res_ptr == NULL)
X	        res_ptr = min_ptr;
X	}
X    }
X
X    /* send result */
X    if (res_ptr == NULL)
X        (void) strcpy(locinfo.hostname, "local");
X    else {
X        ++(res_ptr->created_num);
X        (void) strcpy(locinfo.hostname, res_ptr->hostname);
X    }
X
X#else /* Not USE_MAPFILE */
X
X    /* Determine the location where to create the process with name 'pname'.
X     */
X
X    result = NULL;
X
X    if (!(psymbol = lookup_symbtabel(pname))) {
X	fprintf(stderr, "dcadmin: warning: can't find process \"%s\" in symbol table\n", pname);
X	fprintf(stderr, "dcadmin: resulting node for process creation is local node!\n");
X	result = NULL;
X    } else {
X
X	if (check_allocation) {
X	    fprintf(stderr, "Enter location of creator process: ");
X	    scanf("%s", creat_loc);
X	    clocation = &(creat_loc[0]);
X	}
X
X#ifdef ADMINDEBUG
X	fprintf(dfile, "node of creator process is \"%s\"\n", clocation);
X#endif /* ADMINDEBUG /**/
X
X	if (!(crea_symb = lookup_symbtabel(clocation))) {
X	    fprintf(stderr, "dcadmin: warning: can't find creator host \"%s\" in symbol table\n", clocation);
X	    fprintf(stderr, "dcadmin: resulting node for process creation is local node!\n");
X	    result = NULL;
X	} else {
X	    best_index = 0;
X	    for(phostl = psymbol->info.Process.phostlist; phostl; phostl = phostl->next) {
X		hsymbol = phostl->Host;
X
X		for(costl = crea_symb->info.Host.costinfo; costl; costl = costl->next) {
X		    if (costl->dest_host == hsymbol)
X			break;
X		}
X
X# ifdef ADMINDEBUG
X		fprintf(dfile, "\nCalculating criterions for host %s:\n", phostl->Host->name);
X# endif /* ADMINDEBUG /**/
X
X		/* consider load of already created processes */
X		oload_val = phostl->Host->info.Host.prob_load;
X
X		/* consider process creation costs */
X	    	crea_val = costl->crea_val; 
X
X		/* consider interprocess communication costs */
X# ifdef DO_IPC_TOO
X		ipc_val = 0.0;
X		for(coml = psymbol->info.Process.commps; coml; coml = coml->next) {
X    		    for(pdatl = pdat_first; pdatl; pdatl = pdatl->next) {
X        		if (!strcmp(coml->Process->name, pdatl->p_descr.processname)) {
X	    		    for(costl2 = psymbol->info.Host.costinfo; costl2; costl2 = costl2->next) {
X#  if defined(SCO_UNIX)
X				if (!strcmp(costl2->dest_host->name, pdatl->hostname)) {
X#  else
X				    if (!strcmp(costl2->dest_host->name, pdatl->p_descr.port.hostname)) {
X#  endif
X		    			ipc_val += costl2->comm_val * coml->frequency * coml->quantity;
X				    }
X				}
X	    		    } /* for(costl2) */
X			}
X    		    } /* for(pdatl) */
X		} /* for(coml) */
X# endif /* DO_IPC_TOO /**/
X
X# ifdef ADMINDEBUG
X		fprintf(dfile, "CRITERION VALUES (without egalization, without priorities)\n");
X		fprintf(dfile, "                  preferred host : %d\n", phostl->preferred); 
X		fprintf(dfile, "  accomplished wished ressources : %d\n", phostl->wished_val); 
X		fprintf(dfile, "           probably load without : %3.2f\n", phostl->load); 
X		fprintf(dfile, "              probably load with : %3.2f\n", oload_val);
X		fprintf(dfile, "                  creation costs : %3.2f\n", crea_val);
X		fprintf(dfile, "interprocess communication costs : %3.2f\n\n", ipc_val);
X# endif /* ADMINDEBUG /**/
X
X		h1 = phostl->preferred  EGALIZE_PREF;
X		h2 = phostl->wished_val EGALIZE_WISH;
X		h3 = (1 / phostl->load) EGALIZE_LOAD;
X		h4 = (oload_val < 0.01) ? 0 : oload_val EGALIZE_CLOAD;
X		h5 = (crea_val < 0.01) ? 500 : (1 / crea_val) EGALIZE_CREA;
X		h6 = ipc_val EGALIZE_IPC;
X
X# ifdef ADMINDEBUG
X		fprintf(dfile, "CRITERION VALUES (with egalization, without priorities)\n");
X		fprintf(dfile, "                  preferred host : %3.2f\n", h1); 
X		fprintf(dfile, "  accomplished wished ressources : %3.2f\n", h2); 
X		fprintf(dfile, "           probably load without : %3.2f\n", h3); 
X		fprintf(dfile, "              probably load with : %3.2f\n", h4);
X		fprintf(dfile, "                  creation costs : %3.2f\n", h5);
X		fprintf(dfile, "interprocess communication costs : %3.2f\n\n", h6);
X# endif /* ADMINDEBUG /**/
X
X		h1 += critprio_preferred;
X		h2 += critprio_wished;
X		h3 += critprio_load;
X		h4 += critprio_cload;
X		h5 += critprio_crea;
X		h6 += critprio_ipc;
X
X# ifdef ADMINDEBUG
X		fprintf(dfile, "CRITERION VALUES (with egalization, with priorities)\n");
X		fprintf(dfile, "                  preferred host : %3.2f\n", h1); 
X		fprintf(dfile, "  accomplished wished ressources : %3.2f\n", h2); 
X		fprintf(dfile, "           probably load without : %3.2f\n", h3); 
X		fprintf(dfile, "              probably load with : %3.2f\n", h4);
X		fprintf(dfile, "                  creation costs : %3.2f\n", h5);
X		fprintf(dfile, "interprocess communication costs : %3.2f\n\n", h6);
X# endif /* ADMINDEBUG /**/
X
X		dcadmin_index = h1 + h2 + h3 - h4 + h5 - h6;
X
X# ifdef ADMINDEBUG
X		  fprintf(dfile, "process: %s, node: %s, dcadmin_index = %5.4f\n", 
X			pname, phostl->Host->name, dcadmin_index);
X# endif /* ADMINDEBUG /**/
X
X		if (dcadmin_index > best_index) {
X    		    result = strcpy(locinfo.hostname, phostl->Host->name);
X    		    best_index = dcadmin_index;
X		}
X
X	    } /* for(phostl) */
X 	} /* if (!(crea_symb)) */
X    } /* if (!(psymbol)) */
X
X    if (!result)
X	strcpy(locinfo.hostname, "local");
X#endif /* USE_MAPFILE /**/
X
X#ifdef ADMINDEBUG
X    fprintf(dfile, "[dbg] %s LOCATION is \"%s\"\n", _processprefix, locinfo.hostname);
X    if (_debugflush)
X	fflush(dfile);
X#endif /* ADMINDEBUG /**/
X
X    fprintf(stderr, "dcadmin: target node for process \"%s\" is \"%s\"\n",
X	pname, locinfo.hostname);
X
X#ifndef USE_MAPFILE
X    /* actualize probably host load */
X    hsymbol = lookup_symbtabel(locinfo.hostname);
X    if (!psymbol || !hsymbol)
X        return(ERROR);
X    hsymbol->info.Host.prob_load += psymbol->info.Process.intensity_index / hsymbol->info.Host.perf_index;
X#endif
X
X    if (check_allocation) {
X#ifndef USE_MAPFILE
X        printf("Probably load at host %s is now %3.2f\n", 
X            hsymbol->name, hsymbol->info.Host.prob_load);
X#endif
X	/* insert process in list */
X	/* create a new process data list element */
X#ifndef USE_MAPFILE
X        if (pdatptr = (struct pdat_list *) malloc(sizeof(struct pdat_list))) {
X    	    /* store the new process in the process data list */
X    	    strcpy(pdatptr->p_descr.processname, pname);
X    	    pdatptr->p_descr.pid  = -1;
X# ifdef SCO_UNIX
X    	    strcpy(pdatptr->hostname, hsymbol->name);
X# else
X    	    strcpy(pdatptr->p_descr.port.hostname, hsymbol->name);
X# endif
X    	    pdatptr->status = RUNNING;
X    	    pdatptr->next = pdat_first;
X    	    pdat_first = pdatptr;
X	}
X#endif /* Not USE_MAPFILE */
X	return(1);
X    } else {
X        /* send result back */
X#if defined(SINGLE) || defined(HOMOGENEOUS)
X        if (_send_data(&_con_port, (char *) &locinfo, sizeof(ADMINLOCINFO), ADMINLOCTIME) < 0) {
X#else /* HETEROGENEOUS */
X        if (_send_data_encoded(&_con_port, (char *) &locinfo, xdr_ADMINLOCINFO, ADMINLOCTIME)) {
X#endif /* SINGLE || HOMOGENEOUS /**/
X	    if (Errno == ETIMEOUT)
X	        Errno = ETCADSNDLOC;
X	    error("determining creation location");
X	    EXIT(ERROR);
X        }
X    }
X
X    return(OK);
X} /* DetermineCreationLocation */
END_OF_FILE
if test 15073 -ne `wc -c <'dcadmin/Location.c'`; then
    echo shar: \"'dcadmin/Location.c'\" unpacked with wrong size!
fi
# end of 'dcadmin/Location.c'
fi
if test -f 'dcadmin/main.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dcadmin/main.c'\"
else
echo shar: Extracting \"'dcadmin/main.c'\" \(16102 characters\)
sed "s/^X//" >'dcadmin/main.c' <<'END_OF_FILE'
X/***************************************************************************
X *                                                                         *
X * @@@@  @@@ @@@@@ @@@@@ @@@@@ @@@ @@@@  @   @ @@@@@ @@@@@ @@@@       @@@  *
X * @   @  @  @       @   @   @  @  @   @ @   @   @   @     @   @     @   @ *
X * @   @  @  @@@@@   @   @@@@@  @  @@@@@ @   @   @   @@@@@ @   @     @     *
X * @   @  @      @   @   @ @    @  @   @ @   @   @   @     @   @     @   @ *
X * @@@@  @@@ @@@@@   @   @  @  @@@ @@@@  @@@@@   @   @@@@@ @@@@       @@@  *
X *                                                                         *
X *              A compiler for distributed programming with C              *
X *                                                                         *
X *                               m a i n . c                               *
X *                                                                         *
X *                            Package : Administration Process             *
X *                            Version : 1.0                                *
X *                       CreationDate : 16.09.90                           *
X *                         LastUpDate : 06.12.93                           *
X *                                                                         *
X *            The routine 'main' of the administration process.            *
X *                                                                         *
X *                  Portions Copyright 1990 Franz Distler                  *
X *               Copyright (C) 1990-1994 by Christoph Pleier               *
X *                          All rights reserved!                           *
X ***************************************************************************/
X
X/*
X * This file is part of the Distributed C Development Environment (DCDE).
X * DCDE is free software; you can redistribute it and/or modify
X * it under the terms written in the README-file. 
X * DCDE is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
X * See the file README for more details.
X */
X
X#ifdef UNICOS
Xint errno;
X#endif
X
X#include <stdio.h>
X#include <sys/types.h>
X#ifdef HETEROGENEOUS
X# include <rpc/rpc.h>
X#endif
X#include <errno.h>
X#define symbtabel dcc_symbtabel
X#define SYMBTABEL DCCSYMBTABEL
X#include "ipc.h"
X#include "dcc.h"
X#include "run_Errno.h"
X#include "timeout.h"
X#include "version.h"
X#undef symbtabel 
X#undef SYMBTABEL
X#include "cfgparsers.h"
X#include "dcadmin.h"
X#include "location.h"
X
X/*
X * global variables
X */
X
Xint                 Errno,	    /* storing error codes                    */
X                    Intr = 0,	    /* indicating interrupt or not            */
X                    shutdown,	    /* flag if to terminate all processes     */
X                    terminate,      /* flag if to finish own execution        */
X                    check_allocation; /* check allocation of processes or not */
Xlong                _pidcount;      /* unused, but needed!                    */
Xchar               *_programname,   /* the program name                       */
X                   *_processname,   /* the process name                       */
X		    _processprefix[80], /* the prefix specifying the process  */
X                    configfilename[MAXPATHNAMELEN]; /* name of config file    */
XFILE               *dfile;	    /* debug file storing debug infos         */
XADMINREQUEST        req_type;       /* to store request types                 */
XPORTDESCR           _creator_port,  /* port of creator process                */
X                    _own_port,      /* own port                               */
X                    _admin_port,    /* unused, but needed!                    */
X                    dummy_port;     /* a dummy port                           */
XCONNECTIONDESCR     _con_port;      /* to store connection descriptors        */
Xstruct pdat_list   *pdat_first;     /* anchor of process status list          */
X#ifdef USE_MAPFILE
Xstruct pcreat_list *pcreat_first,   /* anchor to begin of process creation    */
X                   *pcreat_last;    /* anchor to end of process creation list */
X#else
Xint                 local_flag;     /* create processes at local host or not  */
X#endif /* USE_MAPFILE /**/
Xfloat               critprio_preferred;
Xfloat               critprio_wished;
Xfloat               critprio_load;
Xfloat               critprio_cload;
Xfloat               critprio_crea;
Xfloat               critprio_ipc;
XSYMBTABEL          *symbtab,        /* pointer to beginning of symbol table   */
X                   *last_symb;      /* pointer to end of symbol table         */
X#ifdef HETEROGENEOUS
Xchar               *_dcc_buf,       /* encode/decode buffer for data          */
X                   *_xdr_size_buf;  /* encode/decode buffer for size info     */
XXDR                 encode_xdrs,    /* for encoding data                      */
X                    decode_xdrs,    /* for decoding data                      */
X                    _xdr_encode_size_xdrs,
X                    _xdr_decode_size_xdrs;
X#endif /* HETEROGENEOUS /**/
X#ifdef LINUX
Xint yylineno;
X#endif /* LINUX /**/
X
X#ifdef ADMINDEBUG
X# define DEBUGPUTS(str)		{fprintf(dfile,"[dbg] %s %s\n", _processprefix, str); fflush(dfile);}
X# define DEBUGFPRINTF(f, a)	{fprintf(dfile, f, a); fflush(dfile);}
X#else
X# define DEBUGPUTS(str)		/* nothing */
X# define DEBUGFPRINTF(f, a)	/* nothing */
X#endif /* ADMINDEBUG /**/
X
X#define EXIT(v)			fprintf(stderr, "dcadmin: Terminating!\n"); \
X				exit(v)
X
X/******************************************************************************
X * main()                                                                     *
X *                                                                            *
X * The main function of the administration process.                           *
X *                                                                            *
X * Return values: 0 upon successs / ERROR upon error                          *
X ******************************************************************************/
Xmain(argc, argv)
Xint    argc;
Xchar **argv;
X{
X    int  i, timeout;
X#ifndef USE_MAPFILE
X    FILE *filep;
X#endif
X
X    check_allocation = FALSE;
X#ifndef iPSC
X    if (argc == 1) {
X	fprintf(stderr, "%s\n%s\n%s\n\n", progname, version, copyright);
X	fprintf(stderr, "Error: process manually started!\n\n");
X	DisplayUsage();
X	exit(ERROR);
X    }
X    for(i = 1; i < argc; i++) {
X	if (!strcmp(argv[i], "-check_allocation")) {
X	    check_allocation = TRUE;
X	    continue;
X	}
X
X	if (!strcmp(argv[i], "-f")) {
X            /* Option: "-f filename" */
X            strcpy(configfilename, argv[++i]);
X	    continue;
X        }
X    } /* for(i) */
X#endif /* Not iPSC /**/
X
X    /* 
X     * some initializations 
X     */
X    _programname = *argv;
X    _processname = "administration process";
X    _set_processprefix();
X    shutdown  = terminate = 0;
X    pdat_first   = NULL; 
X#ifdef USE_MAPFILE
X    pcreat_first = NULL;
X    pcreat_last  = NULL;
X#else
X    symbtab = last_symb = NULL;
X    local_flag = FALSE;
X#endif /* USE_MAPFILE /**/
X
X#ifdef ADMINDEBUG
X    /*
X     * open debug file and print header
X     */
X    if (!(dfile = fopen(DEBUGFILENAME, "w"))) {
X	Errno = -1;
X        error("opening protocol file");
X        EXIT(ERROR);
X    }
X    (void) strcpy(_processprefix, "dcadmin: "); 
X    _debugout = dfile;
X    fputs("*****************************************************\n", dfile);
X    fputs("* Distributed C administration process - debug file *\n", dfile);
X    fputs("*****************************************************\n", dfile);
X    if (_debugflush)
X	fflush(dfile);
X#endif /* ADMINDEBUG /**/
X
X    SetSignals();
X
X    if (!check_allocation) {
X
X#ifdef HETEROGENEOUS
X        /* 
X         * allocate heap space for encode/decode buffer 
X         */
X        if (_allocate_encode_decode_buffer(ADMINDCCBUFSIZE)) {
X            error("allocating heap space for encode/decode buffer");
X	    EXIT(ERROR);
X        }
X#endif /* HETEROGENEOUS /**/
X
X        /* 
X         * create own port to receive orders.
X         */ 
X        if (_create_port(&_own_port)) {
X	    error("creating own port");
X	    EXIT(ERROR);
X        }
X
X#ifdef iPSC
X        init_port(&_creator_port, MAIN_NODE, MAIN_PID);
X#else
X# ifdef ADMINDEBUG
X        fprintf(dfile, "[dbg] %s reporting back to creator process\n",
X	    _processprefix);
X        if (_debugflush)
X	    fflush(dfile);
X# endif /* ADMINDEBUG /**/
X        /*
X         * determine port of creator process and report back 
X         */
X        (void) _convert_argv_to_port(&_creator_port, &dummy_port, argv);
X        if (_make_connection(&_con_port, &_own_port, &_creator_port, ADMINCONTIME)){
X	    if (Errno == ETIMEOUT)
X		    Errno = ETCAPTOCPCON;
X	    error("connecting to creator process");
X	    EXIT(ERROR);
X        }
X        if (_send_process_data()) {
X	    error("Sending process data");
X	    EXIT(ERROR);
X        }
X        if (_close_connection(&_con_port)) {
X	    error("closing connection with creator process");
X	    EXIT(ERROR);
X        }
X#endif /* iPSC /**/
X
X        /*
X         * get filename of configuration file
X         */
X        if (GetConfigFilename(configfilename)) {
X	    Errno = -1;
X	    error("error receiving filename of configuration file");
X	    fputs("setting defaultname as filename\n", stderr);
X	    (void) strcpy(configfilename, CONFIGFILE);
X        }
X
X    } /* if (!check_allocation) */
X
X    /* if not specified by user, search it in home directory */
X    if (configfilename[0] == 0)
X	sprintf(configfilename, "%s/%s", getenv("HOME"), CONFIGFILE);
X
X#ifdef USE_MAPFILE
X
X    /*
X     * interpret configuration file 
X     */
X    if (!(yyin = fopen(configfilename, "r"))) {
X        fprintf(stderr, "dcadmin: warning: can't open configuration file '%s'\n",
X		configfilename);
X	fputs("dcadmin: setting creation list to empty list\n", stderr);
X	pcreat_first = NULL;
X    } else {
X        (void) yyparse();
X        (void) close(yyin);
X    }
X
X# ifdef ADMINDEBUG
X    DisplayCreationList();
X# endif /* ADMINDEBUG /**/
X
X#else /* Not USE_MAPFILE */
X
X    /*
X     * read symbol table with program and system informations from 
X     * configuration file.
X     */
X    if (!(filep = fopen(configfilename, "r")) || ReadSymbtab(filep)) {
X	fprintf(stderr, "dcadmin:   error : can't read program and system info file.\n");
X	fprintf(stderr, "dcadmin:  reason : %s\n", sys_errlist[errno]);
X	fprintf(stderr, "dcadmin: warning : generating all unspecified processes at local host!\n");
X	local_flag = TRUE;
X    }
X
X    fscanf(filep, "%f %f %f %f %f %f\n",
X        &critprio_preferred, &critprio_wished, &critprio_load,
X        &critprio_cload, &critprio_crea, &critprio_ipc);
X
X    fclose(filep);
X#endif /* USE_MAPFILE /**/
X
X    if (check_allocation) {
X	fprintf(stderr, "%s\n%s\n%s\n\n", progname, version, copyright);
X#ifdef ADMINDEBUG
X	fprintf(dfile, "\nPriorities of the criterions:\n");
X    	fprintf(dfile, "    %2.1f - preferred host\n", critprio_preferred);
X    	fprintf(dfile, "    %2.1f - wished ressources\n", critprio_wished);
X    	fprintf(dfile, "    %2.1f - minimum load (without)\n", critprio_load);
X    	fprintf(dfile, "    %2.1f - minimum load (with)\n", critprio_cload);
X    	fprintf(dfile, "    %2.1f - creation costs\n", critprio_crea);
X    	fprintf(dfile, "    %2.1f - ipc costs\n\n", critprio_ipc);
X#endif /* ADMINDEBUG /**/
X	fputs("Enter process names. Type \"done\" to stop.\n\n", stderr);
X	while(DetermineCreationLocation())
X	    ;
X	exit(OK);
X    }
X
X    /* The following unlimited loop performs the main job of the administration
X     * process.
X     *
X     * A job is devided in the following steps:
X     *   1. Accept a connection
X     *   2. Receive the request type
X     *   3. Call the appropriate service routine.
X     *   4. Close the connection
X     *   5. Check if there is at least one process running. Otherwise exit.
X     *
X     * Availible services are:
X     *   - NOTIFY_START: 
X     *     Store a new created process in the process data list 
X     *   - NOTIFY_END:
X     *     Delete a terminating process from the process data list
X     *   - NOTIFY_ERROR:
X     *     Force all processes of the process data list to terminate
X     *   - NOTIFY_ACCORTER_ON:
X     *     Change the status of a process to 'accept or terminate'
X     *   - NOTIFY_ACCORTER_OFF:
X     *     Change the status of a process to 'running'
X     *   - NOTIFY_GETLOCATION:
X     *     Determine the location where to create a specific process.
X     *
X     */
X    while(1) {
X	if (shutdown)
X	    DEBUGPUTS("SHUTDOWN activated!");
X	if (terminate)
X	    DEBUGPUTS("TERMINATE activated!");
X	DEBUGPUTS("WAITING for new request");
X	/* Accept a connection: 
X         * If >shutdown< is activated, there have been only processes in the 
X	 * process data list which process' state is 'accept or terminate'.
X	 * If >terminate< is activated, the process list is empty and it looks
X	 * like we can terminate.
X	 * It may happen that a process was started and had not yet got a 
X	 * chance to notify us his existance. Therefore we wait a delay
X	 * until we order the other processes to terminate (shutdown) or 
X	 * until we finish execution (terminate), so that such processes 
X	 * have a chance to connect to us!
X	 */
X	DEBUGPUTS("ACCEPTING a connection");
X	if (shutdown && terminate) {
X	    /* This case should be impossible! Sanity code follows! */
X	    terminate = 0;
X	}
X	timeout = (shutdown) ? SHUTDOWN_DELAY : ((terminate) ? 
X	    TERMINATE_DELAY : ADMINACCTIME);
X        if (_accept_connection(&_con_port, &_own_port, timeout)) {
X	    if (errno == EINTR) {
X		if (shutdown) {
X		    /* No process has connected to us during the shutdown.
X		     * Therefore order all processes to terminate and 
X		     * continue to be able to collect the termination messages!
X		     */
X		    (void) alarm(0);
X		    ShutdownProcesses();
X		    shutdown = 0;
X		    continue;
X	        } else if (terminate) {
X		    /* No process has connected to us during the terminate.
X		     * Therefore finish execution!
X		     */
X	    	    DEBUGPUTS("TERMINATING");
X	    	    exit(OK);
X		}
X	    } else {
X	        error("accepting request");
X	        EXIT(ERROR);
X	    }
X	}
X	DEBUGPUTS("GOT a connection");
X	shutdown = terminate = 0;
X	/* Receive the request type:
X	 * The request type tells us which service is requested by the
X	 * process that has connected to us.
X	 */
X	DEBUGPUTS("RECEIVING request type message");
X#if defined(SINGLE) || defined(HOMOGENEOUS)
X	if (_recv_data(&_con_port, (char *) &req_type, sizeof(ADMINREQUEST), ADMINRCVTIME)<0){
X#else /* HETEROGENEOUS */
X	if (_recv_data_encoded(&_con_port, (char *) &req_type, xdr_ADMINREQUEST, ADMINRCVTIME)){
X#endif /* SINGLE || HOMOGENEOUS /**/
X	    error("receiving request");
X	    EXIT(ERROR);
X	}
X	/* Call the appropriate service routine:
X	 */
X	switch(req_type.request_type) {
X	case NOTIFY_START:
X	    DEBUGPUTS("SERVICE: NOTIFY_START");
X	    StoreNewProcessInList();
X	    break;
X	case NOTIFY_END:
X	    DEBUGPUTS("SERVICE: NOTIFY_END");
X	    DeleteProcessFromList();
X	    break;
X	case NOTIFY_ERROR:
X	    DEBUGPUTS("SERVICE: NOTIFY_ERROR");
X	    KillProcesses();
X	    break;
X	case NOTIFY_ACCORTER_ON:
X	    DEBUGPUTS("SERVICE: NOTIFY_ACCORTER_ON");
X	    ChangeProcessStatus(req_type.request_type);
X	    break;
X	case NOTIFY_ACCORTER_OFF:
X	    DEBUGPUTS("SERVICE: NOTIFY_ACCORTER_OFF");
X	    ChangeProcessStatus(req_type.request_type);
X	    break;
X	case NOTIFY_GETLOCATION:
X	    DEBUGPUTS("SERVICE: NOTIFY_GETLOCATION");
X	    DetermineCreationLocation();
X	    break;
X	default:
X	    error("unknown request");
X	    KillProcesses();
X	    EXIT(ERROR);
X	} /* switch */ 
X	/* Close the connection:
X	 * Close connection and wait for next job.
X	 */
X        if (_close_connection(&_con_port))
X	    error("closing connection");
X#ifdef ADMINDEBUG
X	DisplayProcessList();
X#endif /* ADMINDEBUG /**/
X	DEBUGPUTS("DONE\n");
X	/* Check if there is at least one process running:
X	 * When all other processes have terminated, we activate >terminate<! 
X	 */
X	if (pdat_first == NULL)
X	    terminate = 1;
X    } /* while */
X} /* main */
END_OF_FILE
if test 16102 -ne `wc -c <'dcadmin/main.c'`; then
    echo shar: \"'dcadmin/main.c'\" unpacked with wrong size!
fi
# end of 'dcadmin/main.c'
fi
if test -f 'dclocate/BuildLists.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dclocate/BuildLists.c'\"
else
echo shar: Extracting \"'dclocate/BuildLists.c'\" \(14646 characters\)
sed "s/^X//" >'dclocate/BuildLists.c' <<'END_OF_FILE'
X/***************************************************************************
X *                                                                         *
X * @@@@  @@@ @@@@@ @@@@@ @@@@@ @@@ @@@@  @   @ @@@@@ @@@@@ @@@@       @@@  *
X * @   @  @  @       @   @   @  @  @   @ @   @   @   @     @   @     @   @ *
X * @   @  @  @@@@@   @   @@@@@  @  @@@@@ @   @   @   @@@@@ @   @     @     *
X * @   @  @      @   @   @ @    @  @   @ @   @   @   @     @   @     @   @ *
X * @@@@  @@@ @@@@@   @   @  @  @@@ @@@@  @@@@@   @   @@@@@ @@@@       @@@  *
X *                                                                         *
X *              A compiler for distributed programming with C              *
X *                                                                         *
X *                         B u i l d L i s t s . c                         *
X *                                                                         *
X *                            Package : Locator Program                    *
X *                            Version : 1.1                                *
X *                       CreationDate : 27.02.92                           *
X *                         LastUpDate : 08.03.92                           *
X *                                                                         *
X * The routine 'BuildPriorityLists' which generates the priority lists for *
X * all processes stored in the symbol table.                               *
X *                                                                         *
X *               Copyright (C) 1992-1994 by Christoph Pleier               *
X *                          All rights reserved!                           *
X ***************************************************************************/
X
X/*
X * This file is part of the Distributed C Development Environment (DCDE).
X * DCDE is free software; you can redistribute it and/or modify
X * it under the terms written in the README-file. 
X * DCDE is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
X * See the file README for more details.
X */
X
X#include <stdio.h>
X#include "cfgparsers.h"
X#include "dclocate.h"
X#include "location.h"
X
X/******************************************************************************
X * enter_host_in_list()                                                       *
X *                                                                            *
X * Enters the host specified by 'host' in the list pointed to by 'phostlist'. *
X *                                                                            *
X * Return values: OK upon success / ERROR upon error.                         *
X ******************************************************************************/
Xint
Xenter_host_in_list(phostlist, host)
XPHOSTLIST **phostlist;
XSYMBTABEL *host;
X{
X    register PHOSTLIST *ptr, *ptr2;
X
X    ptr = (PHOSTLIST *) Malloc(sizeof(PHOSTLIST));
X    ptr->Host       = host;
X    ptr->preferred  = FALSE;
X    ptr->wished_val = 0;
X    ptr->load       = 0;
X    ptr->next       = NULL;
X
X    if(!*phostlist)
X	*phostlist = ptr;
X    else {
X        for(ptr2 = *phostlist; ptr2->next; ptr2 = ptr2->next)
X	    ;
X        ptr2->next = ptr;
X    }
X
X    return(OK);
X} /* enter_host_in_list */
X
X/******************************************************************************
X * display_host_list()                                                        *
X *                                                                            *
X * Displays the hostlist pointed to by 'phostlist'.                           *
X *                                                                            *
X * Return values: always OK for success.                                      *
X ******************************************************************************/
Xint
Xdisplay_host_list(phostlist)
XPHOSTLIST *phostlist;
X{
X    for(; phostlist; phostlist = phostlist->next) {
X	printf("    host: %10s, pref: %d, wished_val: %3d, load: %2.2f, overall: %2.2f\n", 
X	    phostlist->Host->name, phostlist->preferred, phostlist->wished_val,
X	    phostlist->load, phostlist->overall_index);
X    }
X    return(OK);
X} /* display_host_list */
X
X/******************************************************************************
X * BuildPriorityLists()                                                       *
X *                                                                            *
X * The function to determine the priority lists for all processes stored in   *
X * the symbol table.                                                          *
X *                                                                            *
X * The lists are generated by performing the following actions:               *
X *                                                                            *
X * For each process stored in the symbol table do:                            *
X * 1. Create new list for actual process with regard to specified restricted  *
X *    hosts and required ressources. The resulting list contains only hosts   *
X *    which accomplish the required ressources and are not restricted.        *
X * 2. Determine for each host the components                                  *
X *    - if host is preferred or not                                           *
X *    - the sum of accomplished wished ressources                             *
X *    - the probably host load.                                               *
X * 3. Put list in priority order with regard to the specified importance of   *
X *    each criterion.                                                         *
X *                                                                            *
X * Return values: OK upon success / ERROR upon error                          *
X ******************************************************************************/
Xint
XBuildPriorityLists()
X{
X    int restricted, peripherals, filesystems, required, preferred;
X    register SYMBTABEL *process, *host;
X    register IDENTLIST *idl, *idl2;
X    register FSSPECINFO *p_fs;
X    register ACCFSINFO *h_fs;
X    register PATTRINFO *pattr;
X    PHOSTLIST *hostlist,*act_new_host, *new_phostlist, *last, *phost, *next;
X
X    /* FIRST: Create new list for actual process with regard to
X     *        - restricted hosts
X     *        - required ressources 
X     */
X
X    for(process = symbtab; process; process = process->next) {
X
X	if (process->type != S_PROCESS)
X	    continue;
X
X	if (verbose)
X	    printf("generating list for process \"%s\"\n", process->name);
X
X	hostlist = NULL;
X
X	for(host = symbtab; host; host = host->next) {
X
X	    if (host->type != S_HOST)
X		continue;
X
X	if (verbose)
X	    printf("    checking host \"%s\"\n", host->name);
X
X	    /* check if actual host is in RESTRICTED HOSTS list */
X	    restricted = FALSE;
X	    for(idl = process->info.Process.rest_hosts; idl; idl = idl->next) {
X		if (idl->symbol == host) {
X		    restricted = TRUE;
X		    break;
X		}
X	    } /* for(idl) */
X
X	    if (verbose) {
X	        if (restricted)
X	    	    puts("        host is in restriction list, discarding it");
X	        else
X		    puts("        host is not in restriction list, continuing");
X	    }
X
X	    /* if actual host is in restricted list, discard actual host */
X	    if (restricted)
X		continue;
X
X	    /* check accomplishment of PERIPHERAL DEVICES */
X	    peripherals = TRUE;
X	    for(idl = process->info.Process.peri_dev; idl; idl = idl->next) {
X	        peripherals = FALSE;
X		for(idl2 = host->info.Host.p_devices; idl2; idl2 = idl2->next) {
X		    if (idl2->symbol == idl->symbol) {
X			peripherals = TRUE;
X			break;
X		    }
X		} /* for(idl2) */
X		if (!peripherals)
X		    break;
X	    } /* for(idl) */
X
X	    if (verbose) {
X	        if (!peripherals)
X		    puts("        host has not all required devices, discarding it");
X	        else
X		    puts("        host has all required devices, continuing");
X	    }
X
X	    /* if actual host hasn't all required peripheral devs, discard it */
X	    if (!peripherals)
X		continue;
X	    
X	    /* check accomplishment of accessed FILESYSTEMS */
X	    filesystems = TRUE;
X	    for(p_fs = process->info.Process.filesystems; p_fs; p_fs = p_fs->next) {
X	        filesystems = FALSE;
X		for(h_fs = host->info.Host.f_systems; h_fs; h_fs = h_fs->next) {
X		    if (h_fs->filesystem == p_fs->filesys) {
X			filesystems = TRUE;
X			break;
X		    }
X		} /* for(h_fs) */
X	    } /* for(p_fs) */
X
X	    if (verbose) {
X	        if (!filesystems)
X		    puts("        host can't access all required filesystems, discarding it");
X	        else
X		    puts("        host can access all required filesystems, continuing");
X	    }
X
X	    /* if actual host can't access all required filesystems, discard it
X	     */
X	    if (!filesystems)
X		continue;
X		
X	    /* check accomplishment of other REQUIRED RESSOURCES */
X	    required = TRUE;
X	    for(pattr = process->info.Process.others; pattr; pattr = pattr->next) {
X		if (pattr->mode != MODE_REQUIRES) 
X		    continue;
X		required = TRUE;
X		switch(pattr->type) {
X		case PA_PHYS_MEM:
X		    if (pattr->info.phys_mem_size > host->info.Host.phys_mem) {
X			required = FALSE;
X		    }
X		    break;
X		case PA_VIRT_MEM:
X		    if (pattr->info.virt_mem_size > host->info.Host.virt_mem) {
X			required = FALSE;
X		    }
X		    break;
X		case PA_VECTORIZATION:
X		    if (!host->info.Host.is_vector_computer)
X			required = FALSE;
X		    break;
X		case PA_PARALLELIZATION:
X		    if (!host->info.Host.has_par_compiler)
X			required = FALSE;
X		    break;
X		} /* switch */
X		if (!required)
X		    break;
X	    } /* for(pattr) */
X
X	    if (verbose) {
X	        if (!required)
X		    puts("        host can't offer all required ressources, discarding it");
X	        else
X		    puts("        host can offer all required ressources, continuing");
X	    }
X
X	    /* if actual host can't offer all required ressources, discard it */
X	    if (!required)
X		continue;
X
X	    if (verbose)
X	        puts("        entering host in list");
X
X	    enter_host_in_list(&hostlist, host);
X
X	} /* for(hosts) */
X
X 	process->info.Process.phostlist = hostlist;
X
X    } /* for(process) */
X
X    if (verbose) {
X        puts("Generated hosts lists (NOT in priority order, WITHOUT additional components):");
X        for(process = symbtab; process; process = process->next) {
X	    if (process->type != S_PROCESS)
X	        continue;
X	    printf("process \"%s\":\n", process->name);
X	    display_host_list(process->info.Process.phostlist);	
X        }
X    }
X
X    /* SECOND: Determine for each host in each host list the components 
X     *         - if host is preferred or not
X     *         - the sum of accomplished wished ressources
X     *         - the probably host load
X     */
X
X    for(process = symbtab; process; process = process->next) {
X
X	if (process->type != S_PROCESS)
X	    continue;
X
X	for(hostlist = process->info.Process.phostlist; hostlist; hostlist = hostlist->next) {
X
X	    /* check if actual host is a preferred host */
X	    preferred = FALSE;
X	    for(idl = process->info.Process.pref_hosts; idl; idl = idl->next) {
X		if (idl->symbol == hostlist->Host) {
X		    hostlist->preferred = TRUE;
X		    break;
X		}
X	    } /* for(idl) */
X
X	    /* determine sum of accomplished wished ressources */
X	    for(pattr = process->info.Process.others; pattr; pattr = pattr->next) {
X		if (pattr->mode != MODE_WISHES)
X		    continue;
X		switch(pattr->type) {
X		case PA_PHYS_MEM:
X		    if (pattr->info.phys_mem_size <= hostlist->Host->info.Host.phys_mem) {
X			hostlist->wished_val++;
X		    }
X		    break;
X		case PA_VIRT_MEM:
X		    if (pattr->info.virt_mem_size <= hostlist->Host->info.Host.virt_mem) {
X			hostlist->wished_val++;
X		    }
X		    break;
X		case PA_VECTORIZATION:
X		    if (hostlist->Host->info.Host.is_vector_computer)
X		        hostlist->wished_val++;
X		    break;
X		case PA_PARALLELIZATION:
X		    if (hostlist->Host->info.Host.has_par_compiler)
X		        hostlist->wished_val++;
X		    break;
X		} /* switch */
X	    } /* for(pattr) */
X
X	    /* determine probable host load */
X	    hostlist->load = process->info.Process.intensity_index / hostlist->Host->info.Host.perf_index;
X
X	} /* for(hostlist) */
X
X    } /* for(process) */
X
X    if (verbose) {
X        puts("Generated hosts lists (NOT in priority order, WITH additional components):");
X        for(process = symbtab; process; process = process->next) {
X	    if (process->type != S_PROCESS)
X	        continue;
X	    printf("process \"%s\":\n", process->name);
X	    display_host_list(process->info.Process.phostlist);	
X        }
X    }
X
X    /* THIRD: Put list in priority order with regard to one or more of 
X     *        the criterions:
X     *        - preferred hosts
X     *        - wished ressources 
X     *        - computer load 
X     */
X
X    for(process = symbtab; process; process = process->next) {
X
X	if (process->type != S_PROCESS)
X	    continue;
X
X	if (verbose)
X	    printf("putting list for process \"%s\" in order\n", process->name);
X
X	/* determine overall index for all hosts in list */
X	for(phost = process->info.Process.phostlist; phost; phost = phost->next) {
X	    phost->overall_index = 
X		  phost->preferred  EGALIZE_PREF + critprio_preferred
X		+ phost->wished_val EGALIZE_WISH + critprio_wished 
X		+ (1 / phost->load) EGALIZE_LOAD + critprio_load;
X	}
X
X	new_phostlist = NULL;
X
X	/* sort list */
X	for(phost = process->info.Process.phostlist; phost; phost = next) {
X
X	    next = phost->next;
X
X	    if (!new_phostlist) {
X		new_phostlist = phost;
X		new_phostlist->next = NULL;
X	    } else {
X	 	last = NULL;
X		for(act_new_host = new_phostlist; act_new_host; act_new_host = act_new_host->next) {
X		    if (phost->overall_index > act_new_host->overall_index) {
X			if (!last) {
X			    phost->next = new_phostlist;
X			    new_phostlist = phost;
X			} else {
X			    last->next = phost;
X			    phost->next = act_new_host;
X			}
X			break;
X		    }
X		    last = act_new_host;
X		} /* for(act_new_host) */
X		if (!act_new_host) {
X		    last->next = phost;
X		    phost->next = NULL;
X		}
X	    }
X
X	} /* for (phost) */
X
X	if (!new_phostlist) {
X	    fprintf(stderr, "WARNING: process \"%s\" can not be located!\n",
X		process->name);
X	}
X
X        process->info.Process.phostlist = new_phostlist;
X
X    } /* for(process) */
X
X
X    if (verbose || show_result) {
X        puts("Generated hosts lists (IN priority order, WITH additional components):");
X        for(process = symbtab; process; process = process->next) {
X	    if (process->type != S_PROCESS)
X	        continue;
X	    printf("process \"%s\":\n", process->name);
X	    display_host_list(process->info.Process.phostlist);	
X        }
X    }
X
X    return(OK);
X} /* BuildPriorityLists */
END_OF_FILE
if test 14646 -ne `wc -c <'dclocate/BuildLists.c'`; then
    echo shar: \"'dclocate/BuildLists.c'\" unpacked with wrong size!
fi
# end of 'dclocate/BuildLists.c'
fi
echo shar: End of archive 11 \(of 18\).
cp /dev/null ark11isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 18 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
