#include <locale.h>
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <sys/mman.h>
#include <tsol/label.h>
#include "clnt.h"
#include "labeld.h"
static char *slcvt = NULL;
static int slcvtsize = 0;
static char *sldim;
static char *slstring = NULL;
static int slstringsize = 0;
static brange_t sbounds;
static char *clrcvt = NULL;
static int clrcvtsize = 0;
static char *clrdim;
static char *clrstring = NULL;
static int clrstringsize = 0;
static brange_t cbounds;
static
int
alloc_words(char **words, const size_t size)
{
if (*words == NULL) {
if ((*words = malloc(size)) == NULL)
return (0);
} else {
if ((*words = realloc(*words, size)) == NULL) {
return (0);
}
}
return (1);
}
static
int
build_strings(int *static_string_size, char **static_string, char *new_string,
int *static_words_size, int new_words_size, char **static_words,
char **static_dimming, int number_of_words, char *long_words,
char *short_words, char *dimming_list, int full)
{
char **l;
char **s;
char *w;
char *l_w = long_words;
char *s_w = short_words;
int i;
int len;
int newsize;
if (*static_string_size == 0) {
if ((*static_string_size = alloc_string(static_string,
*static_string_size, 'C')) == 0)
return (0);
}
again:
if (*static_string_size < (int)strlen(new_string)+1) {
if ((newsize = alloc_string(static_string, *static_string_size,
'C')) == 0)
return (0);
*static_string_size += newsize;
goto again;
}
bcopy(new_string, *static_string, strlen(new_string) + 1);
if (full) {
if (*static_words_size < new_words_size &&
!alloc_words(static_words, new_words_size)) {
return (0);
} else {
*static_words_size = new_words_size;
}
l = (char **)*static_words;
s = l + number_of_words;
*static_dimming = (char *)(s + number_of_words);
w = *static_dimming + number_of_words;
for (i = 0; i < number_of_words; i++) {
*l = w;
(void) strcpy(w, l_w);
w += (len = strlen(l_w) + 1);
l_w += len;
if (*s_w == '\000') {
*s = NULL;
s_w++;
} else {
*s = w;
(void) strcpy(w, s_w);
w += (len = strlen(s_w) + 1);
s_w += len;
}
l++;
s++;
}
}
bcopy(dimming_list, *static_dimming, number_of_words);
return (1);
}
#define bsfcall callp->param.acall.cargs.bslcvt_arg
#define bsfret callp->param.aret.rvals.bslcvt_ret
int
bslcvtfull(const bslabel_t *label, const blrange_t *bounds, int flags,
char **string, char **long_words[], char **short_words[], char *display[],
int *first_compartment, int *display_size)
{
labeld_data_t call;
labeld_data_t *callp = &call;
size_t bufsize = sizeof (labeld_data_t);
size_t datasize = CALL_SIZE(bslcvt_call_t, 0);
int new_words_size;
int rval;
call.callop = BSLCVT;
bsfcall.label = *label;
bsfcall.bounds.upper_bound = *bounds->upper_bound;
bsfcall.bounds.lower_bound = *bounds->lower_bound;
bsfcall.flags = LABELS_FULL_CONVERT;
set_label_view(&bsfcall.flags, flags);
if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
#ifdef DEBUG
(void) fprintf(stderr, "No label server.\n");
#endif
return (-1);
} else if (rval != SUCCESS) {
return (-1);
} else {
if (callp->reterr != 0)
return (-1);
}
*first_compartment = bsfret.first_comp;
*display_size = bsfret.d_len;
new_words_size = bsfret.l_len + bsfret.s_len + bsfret.d_len +
(2 * sizeof (char *)) * bsfret.d_len;
if (build_strings(&slstringsize, &slstring, &bsfret.buf[bsfret.string],
&slcvtsize, new_words_size, &slcvt, &sldim, bsfret.d_len,
&bsfret.buf[bsfret.lwords], &bsfret.buf[bsfret.swords],
&bsfret.buf[bsfret.dim], 1) != 1) {
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (0);
}
sbounds.upper_bound = *bounds->upper_bound;
sbounds.lower_bound = *bounds->lower_bound;
*string = slstring;
*display = sldim;
*long_words = (char **)slcvt;
*short_words = (char **)(slcvt + *display_size * sizeof (char *));
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (1);
}
#undef bsfcall
#undef bsfret
#define bsccall callp->param.acall.cargs.bslcvt_arg
#define bscret callp->param.aret.rvals.bslcvt_ret
int
bslcvt(const bslabel_t *label, int flags, char **string, char *display[])
{
labeld_data_t call;
labeld_data_t *callp = &call;
size_t bufsize = sizeof (labeld_data_t);
size_t datasize = CALL_SIZE(bslcvt_call_t, 0);
int rval;
if (slcvt == NULL)
return (-1);
call.callop = BSLCVT;
bsccall.label = *label;
bsccall.bounds = sbounds;
bsccall.flags = 0;
set_label_view(&bsccall.flags, flags);
if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
#ifdef DEBUG
(void) fprintf(stderr, "No label server.\n");
#endif
return (-1);
} else if (rval != SUCCESS) {
return (-1);
} else {
if (callp->reterr != 0)
return (-1);
}
if (build_strings(&slstringsize, &slstring, &bscret.buf[bscret.string],
&slcvtsize, 0, &slcvt, &sldim, bscret.d_len,
&bscret.buf[bscret.lwords], &bscret.buf[bscret.swords],
&bscret.buf[bscret.dim], 0) != 1) {
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (0);
}
*string = slstring;
*display = sldim;
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (1);
}
#undef bsccall
#undef bscret
#define bcfcall callp->param.acall.cargs.bclearcvt_arg
#define bcfret callp->param.aret.rvals.bclearcvt_ret
int
bclearcvtfull(const bclear_t *clearance, const blrange_t *bounds,
int flags, char **string, char **long_words[], char **short_words[],
char *display[], int *first_compartment, int *display_size)
{
labeld_data_t call;
labeld_data_t *callp = &call;
size_t bufsize = sizeof (labeld_data_t);
size_t datasize = CALL_SIZE(bclearcvt_call_t, 0);
int new_words_size;
int rval;
call.callop = BCLEARCVT;
bcfcall.clear = *clearance;
bcfcall.bounds.upper_bound = *bounds->upper_bound;
bcfcall.bounds.lower_bound = *bounds->lower_bound;
bcfcall.flags = LABELS_FULL_CONVERT;
set_label_view(&bcfcall.flags, flags);
if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
#ifdef DEBUG
(void) fprintf(stderr, "No label server.\n");
#endif
return (-1);
} else if (rval != SUCCESS) {
return (-1);
} else {
if (callp->reterr != 0)
return (-1);
}
*first_compartment = bcfret.first_comp;
*display_size = bcfret.d_len;
new_words_size = bcfret.l_len + bcfret.s_len + bcfret.d_len +
(2 * sizeof (char *)) * bcfret.d_len;
if (build_strings(&clrstringsize, &clrstring,
&bcfret.buf[bcfret.string],
&clrcvtsize, new_words_size, &clrcvt,
&clrdim, bcfret.d_len,
&bcfret.buf[bcfret.lwords], &bcfret.buf[bcfret.swords],
&bcfret.buf[bcfret.dim], 1) != 1) {
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (0);
}
cbounds.upper_bound = *bounds->upper_bound;
cbounds.lower_bound = *bounds->lower_bound;
*string = clrstring;
*display = clrdim;
*long_words = (char **)clrcvt;
*short_words = (char **)(clrcvt + *display_size * sizeof (char *));
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (1);
}
#undef bcfcall
#undef bcfret
#define bcccall callp->param.acall.cargs.bclearcvt_arg
#define bccret callp->param.aret.rvals.bclearcvt_ret
int
bclearcvt(const bclear_t *clearance, int flags, char **string,
char *display[])
{
labeld_data_t call;
labeld_data_t *callp = &call;
size_t bufsize = sizeof (labeld_data_t);
size_t datasize = CALL_SIZE(bclearcvt_call_t, 0);
int rval;
if (clrcvt == NULL)
return (-1);
call.callop = BCLEARCVT;
bcccall.clear = *clearance;
bcccall.bounds = cbounds;
bcccall.flags = 0;
set_label_view(&bcccall.flags, flags);
if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
#ifdef DEBUG
(void) fprintf(stderr, "No label server.\n");
#endif
return (-1);
} else if (rval != SUCCESS) {
return (-1);
} else {
if (callp->reterr != 0)
return (-1);
}
if (build_strings(&clrstringsize, &clrstring,
&bccret.buf[bccret.string],
&clrcvtsize, 0, &clrcvt, &clrdim, bccret.d_len,
&bccret.buf[bccret.lwords], &bccret.buf[bccret.swords],
&bccret.buf[bccret.dim], 0) != 1) {
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (0);
}
*string = clrstring;
*display = clrdim;
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (1);
}
#undef bcccall
#undef bccret
#define lfret callp->param.aret.rvals.fields_ret
int
labelfields(struct name_fields *fields)
{
labeld_data_t call;
labeld_data_t *callp = &call;
size_t bufsize = sizeof (labeld_data_t);
size_t datasize = CALL_SIZE(fields_call_t, 0);
int rval;
call.callop = LABELFIELDS;
if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (-1);
}
if ((fields->class_name = strdup(&lfret.buf[lfret.classi])) == NULL) {
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (0);
}
if ((fields->comps_name = strdup(&lfret.buf[lfret.compsi])) == NULL) {
free(fields->class_name);
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (0);
}
if ((fields->marks_name = strdup(&lfret.buf[lfret.marksi])) == NULL) {
free(fields->class_name);
free(fields->comps_name);
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (0);
}
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (rval);
}
#undef lfret
#define udret callp->param.aret.rvals.udefs_ret
int
userdefs(bslabel_t *sl, bclear_t *clear)
{
labeld_data_t call;
labeld_data_t *callp = &call;
size_t bufsize = sizeof (labeld_data_t);
size_t datasize = CALL_SIZE(udefs_call_t, 0);
int rval;
call.callop = UDEFS;
if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
return (-1);
}
if (sl != NULL)
*sl = udret.sl;
if (clear != NULL)
*clear = udret.clear;
return (rval);
}
#undef udret