1
0
Files
irix-657m-src/eoe/cmd/tsix/satmpd/server.c
2022-09-29 17:59:04 +03:00

468 lines
10 KiB
C

#ident "$Revision: 1.4 $"
#include <sys/types.h>
#include <sys/endian.h>
#include <sys/t6satmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <limits.h>
#include <ctype.h>
#include "list.h"
#include "match.h"
#include "parse.h"
#include "request.h"
#include "server.h"
#include "lrep.h"
#include "debug.h"
#include "ref.h"
#include "sem.h"
static struct server *srvr_handle;
u_int server_generation;
int
receive_get_tok_request (get_tok_request *req, get_tok_reply *rep)
{
u_short i;
int status = SATMP_REPLY_OK;
rep->hostid = 0;
rep->generation = srvr_handle->generation;
rep->token_spec_count = 0;
rep->token_spec = malloc (req->attr_spec_count *
sizeof (*rep->token_spec));
if (rep->token_spec == NULL)
return (SATMP_INTERNAL_ERROR);
for (i = 0; i < req->attr_spec_count; i++)
{
u_int token;
void *lr;
/* find the token corresponding to this network
representation */
lr = lrep_from_nrep (req->attr_spec[i].nr,
req->attr_spec[i].attribute,
req->attr_spec[i].domain);
if (attr_to_token (req->attr_spec[i].domain,
req->attr_spec[i].attribute,
lr, &token))
{
destroy_lrep (lr, req->attr_spec[i].attribute);
status = SATMP_TRANSLATION_ERROR;
continue;
}
/* initialize new token_spec */
rep->token_spec[rep->token_spec_count].attribute =
req->attr_spec[i].attribute;
rep->token_spec[rep->token_spec_count].mid =
req->attr_spec[i].mid;
rep->token_spec[rep->token_spec_count++].token = token;
}
return (status);
}
int
receive_get_lrtok_request (get_lrtok_request *req, get_lrtok_reply *rep)
{
u_short i;
rep->hostid = req->hostid;
rep->generation = srvr_handle->generation;
rep->token_spec_count = req->attr_spec_count;
rep->token_spec = malloc (req->attr_spec_count *
sizeof (*rep->token_spec));
if (rep->token_spec == NULL)
return (SATMP_INTERNAL_ERROR);
for (i = 0; i < req->attr_spec_count; i++)
{
u_int token;
/* initialize new token_spec */
rep->token_spec[i].attribute = req->attr_spec[i].attribute;
rep->token_spec[i].mid = req->attr_spec[i].mid;
rep->token_spec[i].token = 0;
/* check for lack of domain */
if (req->attr_spec[i].domain == NULL)
{
rep->token_spec[i].status = SATMP_NO_DOT;
continue;
}
/* find the token corresponding to this network
representation */
if (attr_to_token (req->attr_spec[i].domain,
req->attr_spec[i].attribute,
req->attr_spec[i].lr, &token))
{
rep->token_spec[i].status = SATMP_TRANSLATION_ERROR;
continue;
}
rep->token_spec[i].status = SATMP_REPLY_OK;
rep->token_spec[i].token = token;
}
return (SATMP_REPLY_OK);
}
/*
* Map a token to the network representation of an entry in the database.
* Not matching a database entry is an error. The database must be locked
* before calling this function.
*/
static int
token_to_nr (const char *domain, u_short attrid, u_int token,
struct _nrep *nrepp)
{
struct attrname *an;
struct domain *d;
struct attrval *av;
int error = 0;
/* search for matching attribute type */
an = first_that (&srvr_handle->attribute_names, match_attrname_byid,
&attrid);
if (an == NULL)
return (1);
/* find matching domain name */
d = first_that (&an->domains, match_domain_byname, domain);
decref (an);
if (d == NULL)
return (1);
/* find matching nrep */
av = first_that (&d->attrvals, match_attrval_bytoken, &token);
decref (d);
if (av == NULL)
return (1);
if (nrepp)
{
*nrepp = av->_nr;
nrepp->_nrep = (char *) malloc (nrepp->_nrep_len);
if (nrepp->_nrep != NULL)
memcpy (nrepp->_nrep, av->_nr._nrep, nrepp->_nrep_len);
else
error = 1;
}
decref (av);
return (error);
}
/*
* Map a token to the local representation of an entry in the database.
* Not matching a database entry is an error. The database must be locked
* before calling this function.
*/
#if 0
static int
token_to_lrep (const char *domain, u_short attrid, u_int token,
struct _lrep **lrepp)
{
struct attrname *an;
struct domain *d;
struct attrval *av;
/* search for matching attribute type */
an = first_that (&srvr_handle->attribute_names, match_attrname_byid,
&attrid);
if (an == NULL)
return (1);
/* find matching domain name */
d = first_that (&an->domains, match_domain_byname, domain);
if (d == NULL)
return (1);
/* find matching lrep */
av = first_that (&d->attrvals, match_attrval_bytoken, &token);
if (av == NULL)
return (1);
if (lrepp)
*lrepp = &av->_lr;
return (0);
}
#endif
int
receive_get_attr_request (get_attr_request *req, get_attr_reply *rep)
{
u_short i;
int status = SATMP_REPLY_OK;
rep->hostid = 0;
rep->generation = req->generation;
rep->attr_spec_count = 0;
/* check generation */
if (srvr_handle->generation != req->generation)
return (SATMP_INVALID_GENERATION);
rep->attr_spec = malloc (req->token_spec_count *
sizeof (*rep->attr_spec));
if (rep->attr_spec == NULL)
return (SATMP_INTERNAL_ERROR);
for (i = 0; i < req->token_spec_count; i++)
{
struct _nrep nr;
/* find the network representation corresponding to this
token */
if (token_to_nr (req->token_spec[i].domain,
req->token_spec[i].attribute,
req->token_spec[i].token, &nr))
{
status = SATMP_NO_MAPPING;
continue;
}
/* initialize new attr_spec */
rep->attr_spec[rep->attr_spec_count].attribute =
req->token_spec[i].attribute;
rep->attr_spec[rep->attr_spec_count].nr_length = nr._nrep_len;
rep->attr_spec[rep->attr_spec_count].token =
req->token_spec[i].token;
rep->attr_spec[rep->attr_spec_count].nr = (char *) malloc (rep->attr_spec[rep->attr_spec_count].nr_length);
if (rep->attr_spec[rep->attr_spec_count].nr == NULL)
{
destroy_get_attr_reply (rep);
return (SATMP_INTERNAL_ERROR);
}
memcpy (rep->attr_spec[rep->attr_spec_count++].nr, nr._nrep,
nr._nrep_len);
free ((void *) nr._nrep);
}
return (status);
}
/*
* Map an attribute in native binary representation to a token in
* the server database. Entries not in the database are added to it.
*/
int
attr_to_token (const char *domain, u_short attrid, void *attr, u_int *token)
{
struct attrname *an;
struct domain *d = NULL;
struct attrval *av;
if (domain == NULL || attr == NULL)
return (1);
/* search for matching attribute type */
an = first_that (&srvr_handle->attribute_names, match_attrname_byid,
&attrid);
if (an == NULL)
goto out;
/* search for matching domain */
d = first_that (&an->domains, match_domain_byname, domain);
if (d == NULL)
{
d = initialize_domain (domain, an->attrid);
if (d == NULL)
{
decref (an);
goto out;
}
add_to_list (&an->domains, d);
}
decref (an);
/* see if this attribute value exists */
av = first_that (&d->attrvals, match_attribute (attrid), attr);
if (av == NULL)
{
char *nrepp;
void *lr;
size_t nrep_size, lrep_size;
lr = lrep_copy (attr, attrid, &lrep_size);
if (lr == NULL)
goto out;
nrepp = lrep_to_nrep (lr, attrid, domain, &nrep_size);
if (nrepp == NULL)
{
destroy_lrep (lr, attrid);
goto out;
}
av = initialize_attrval (lr, lrep_size, nrepp, nrep_size,
&d->seqno, attrid);
free (nrepp);
if (av == NULL)
{
destroy_lrep (lr, attrid);
goto out;
}
add_to_list (&d->attrvals, av);
}
decref (d);
if (token)
*token = av->token;
decref (av);
return (0);
out:
decref (d);
return (1);
}
#if 0
char *
attribute_to_text (u_short attrid)
{
struct attrname *a;
char *unknown = "unknown attribute";
a = first_that (&srvr_handle->attribute_names, match_attrname_byid,
&attrid);
return (a != NULL ? a->name : unknown);
}
#endif
u_short
attribute_from_text (const char *name)
{
struct attrname *a;
u_short attrid;
a = first_that (&srvr_handle->attribute_names, match_attrname_byname,
name);
attrid = (a != NULL ? a->attrid : BAD_ATTRID);
decref (a);
return (attrid);
}
/*
* create attribute<->attribute name map
*/
static int
configure_attribute_names (Generic_list *name_map, const char *configdir)
{
char attrfile[PATH_MAX], buf[BUFSIZ];
FILE *fp;
int lineno = 0;
/* open config file */
sprintf (attrfile, "%s/ATTRIDS", configdir);
if (debug_on (DEBUG_FILE_OPEN))
debug_print ("opening file \"%s\"\n", attrfile);
fp = fopen (attrfile, "r");
if (fp == NULL)
{
if (debug_on (DEBUG_OPEN_FAIL))
debug_print ("can't open file \"%s\"\n", attrfile);
return (1);
}
while (fgets (buf, sizeof (buf), fp) != NULL)
{
struct attrname *a;
char *name, *valuep, *end, *p;
u_short value;
/* update line count */
lineno++;
/* skip empty lines, allow # as comment character */
p = buf;
while (*p != '\0' && isspace (*p))
p++;
if (*p == '\n' || *p == '#' || *p == '\0')
continue;
/* assign fields */
name = p;
valuep = skipfield (name, ':');
/* remove trailing whitespace from name */
p = name + strlen (name);
while (p != name && isspace (*(p - 1)))
*--p = '\0';
/* remove leading & trailing whitespace from valuep */
while (*valuep != '\0' && isspace (*valuep))
valuep++;
p = valuep + strlen (valuep);
while (p != valuep && isspace (*(p - 1)))
*--p = '\0';
/* convert to short */
value = (u_short) strtoul (valuep, &end, 10);
if ((value == 0 && end == valuep) || *end != '\0')
{
debug_print ("%s (line %d): %s: cannot convert to short integer\n", attrfile, lineno, valuep);
fclose (fp);
return (1);
}
a = initialize_attrname (name, value);
if (a == NULL)
{
debug_print ("%s (line %d): %s/%hu: cannot convert name/value pair\n", attrfile, lineno, name, value);
fclose (fp);
return (1);
}
add_to_list (name_map, a);
decref (a);
}
fclose (fp);
return (0);
}
int
configure_server (const char *configdir)
{
const char *default_configdir = "/etc/satmpd";
if (configdir == NULL)
configdir = default_configdir;
srvr_handle = initialize_server ();
if (srvr_handle == NULL)
return (1);
server_generation = srvr_handle->generation;
if (configure_attribute_names (&srvr_handle->attribute_names,
configdir))
{
deconfigure_server ();
return (1);
}
if (debug_on (DEBUG_STARTUP))
print_server (srvr_handle);
return (0);
}
void
deconfigure_server (void)
{
if (srvr_handle != NULL)
{
decref (srvr_handle);
srvr_handle = NULL;
}
}