mslplib_regipc.cpp [plain text]
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "mslp_sd.h"
#include "slp.h"
#include "mslp.h"
#include "mslpd_store.h"
#include "mslp_dat.h"
#include "mslplib.h"
#ifdef EXTRA_MSGS
static int copy_till_entry(FILE *fpSrc,FILE *fpDest, const char *pcURL,
const char *pcLang, const char *pcSt);
static SLPInternalError add_entry(FILE *fpDest, const char *pcURL, const char *pcLang,
unsigned short usLifetime, const char *pcSt);
static SLPInternalError serialize_attributes(FILE *fpDest,
MslpHashtable *phash,const char *pcAtt);
static int scan_till_next_entry(MslpHashtable *phash, FILE *fpDest);
static void copy_remaining(FILE *fpSrc,FILE *fpDest);
static SLPInternalError mslplib_regipc_rename(const char *pc1, const char *pc2);
SLPInternalError mslplib_Reg( UA_State *puas,
const char *pcURL,
unsigned short usLifetime,
const char *pcSt,
const char *pcAtt,
SLPBoolean fresh)
{
SLPInternalError err = SLP_OK;
FILE *fpSrc = NULL;
FILE *fpDest = NULL;
const char *pcPropertyLang = SLPGetProperty("net.slp.locale");
SDLock(puas->pvMutex);
if ((fpSrc = fopen(SLPGetProperty("com.sun.slp.regfile"),"rb")) == NULL)
{
char buf[160];
sprintf(buf,
"mslplib_Reg: [WARNING] regfile \"%s\" could not be opened: %s\n\tAssume we should start a new regfile.",
SLPGetProperty("com.sun.slp.regfile"),strerror(errno));
SLP_LOG( SLP_LOG_DEBUG,buf);
}
if ((fpDest = fopen(SLPGetProperty("com.sun.slp.tempfile"),"wb")) == NULL)
{
char buf[160];
sprintf(buf,"mslplib_Reg: regfile could not be opened: %s", strerror(errno));
err = SLP_INTERNAL_SYSTEM_ERROR;
LOG(SLP_LOG_ERR,buf);
goto mslplib_Reg_done;
}
if (!fpSrc)
{
if (((err = add_entry(fpDest,pcURL,pcPropertyLang,usLifetime,pcSt)) != SLP_OK)
|| ((err = serialize_attributes(fpDest,NULL,pcAtt)) != SLP_OK))
{
LOG(SLP_LOG_ERR,"mslplib_Reg: entry or attributes had problems");
goto mslplib_Reg_done;
}
}
else if (copy_till_entry(fpSrc, fpDest, pcURL, pcPropertyLang, pcSt) < 0 != SLP_OK)
{
LOG(SLP_LOG_ERR,"mslplib_Reg: could not copy regfile to destfile");
err = SLP_INVALID_REGISTRATION;
goto mslplib_Reg_done;
}
else
{
int more;
MslpHashtable *phash;
if (fresh == SLP_TRUE)
phash = NULL;
else
phash = mslp_hash_init();
if ((more=scan_till_next_entry(phash,fpSrc)) < 0)
{
LOG(SLP_LOG_ERR,"mslplib_Reg: could not scan till next entry");
err = (SLPInternalError) more;
goto mslplib_Reg_done;
}
else if (more == 0)
{
if ( ((err = add_entry(fpDest,pcURL,pcPropertyLang,usLifetime,pcSt)) != SLP_OK)
|| ((err = serialize_attributes(fpDest,phash,pcAtt)) != SLP_OK) )
{
LOG(SLP_LOG_ERR,"mslplib_Reg: entry or attributes had problems");
goto mslplib_Reg_done;
}
}
else
{
if (pcSt == NULL)
{
fprintf(fpDest,"%s,%s,%u\n",pcURL, pcPropertyLang, usLifetime);
}
else
{
fprintf(fpDest,"%s,%s,%u,%s\n",pcURL,pcPropertyLang,usLifetime,pcSt);
}
if ((err = serialize_attributes(fpDest,phash,pcAtt)) != SLP_OK)
{
LOG(SLP_LOG_ERR,"mslplib_Reg: could not serialize attributes");
goto mslplib_Reg_done;
}
}
fprintf(fpDest,"\n");
copy_remaining(fpSrc,fpDest);
}
mslplib_Reg_done:
if (fpSrc)
fclose(fpSrc);
if (fpDest)
fclose(fpDest);
if (err == SLP_OK)
err = mslplib_regipc_rename(SLPGetProperty("com.sun.slp.tempfile"), SLPGetProperty("com.sun.slp.regfile"));
SDUnlock(puas->pvMutex);
return err;
}
SLPInternalError mslplib_Dereg(UA_State *puas, const char *pcURL, const char *pcScopes)
{
FILE *fpSrc = NULL, *fpDest = NULL;
SLPInternalError err = SLP_OK;
SDLock(puas->pvMutex);
if ((fpSrc = fopen(SLPGetProperty("com.sun.slp.regfile"),"rb")) == NULL)
{
char buf[160];
sprintf(buf,"mslplib_Reg: regfile could not be opened: %s", strerror(errno));
LOG(SLP_LOG_ERR,buf);
err = SLP_INTERNAL_SYSTEM_ERROR;
goto mslplib_Dereg_done;
}
if ((fpDest = fopen(SLPGetProperty("com.sun.slp.tempfile"),"wb")) == NULL) {
char buf[160];
sprintf(buf,"mslplib_Dereg: temp could not be opened: %s",
strerror(errno));
LOG(SLP_LOG_ERR,buf);
err = SLP_INTERNAL_SYSTEM_ERROR;
goto mslplib_Dereg_done;
}
if (copy_till_entry(fpSrc,fpDest,pcURL,NULL,NULL) < 0)
{
LOG(SLP_LOG_ERR,"mslplib_Dereg: could not scan to find entry to deregister");
err = SLP_INTERNAL_SYSTEM_ERROR;
goto mslplib_Dereg_done;
}
else
{
if (feof(fpSrc))
{
LOG(SLP_LOG_ERR,"mslplib_Dereg: requested URL not in reg file");
err = SLP_INVALID_REGISTRATION;
goto mslplib_Dereg_done;
}
else
{
if (scan_till_next_entry(NULL,fpSrc) < 0)
{
LOG(SLP_LOG_ERR,"mslplib_Dereg: could not scan past the dereg'ed entry");
err = SLP_INTERNAL_SYSTEM_ERROR;
goto mslplib_Dereg_done;
}
copy_remaining(fpSrc,fpDest);
}
}
mslplib_Dereg_done:
if (fpSrc)
fclose(fpSrc);
if (fpDest)
fclose(fpDest);
if (err == SLP_OK)
{
err = mslplib_regipc_rename(SLPGetProperty("com.sun.slp.tempfile"),
SLPGetProperty("com.sun.slp.regfile"));
}
SDUnlock(puas->pvMutex);
return err;
}
static int copy_till_entry(FILE *fpSrc,FILE *fpDest, const char *pcURL,
const char *pcLang, const char *pcSt) {
char pcLine[MAXLINE];
SLPInternalError err = SLP_OK;
char *pcURL_ = NULL;
char *pcLang_ = NULL;
char *pcTemp_ = NULL;
char *pcSt_ = NULL;
char c;
int index = 0;
while(fgets(pcLine,MAXLINE,fpSrc)) {
if (pcLine[0] == ';' || pcLine[0] == '#' ||
pcLine[0] == '\n' || pcLine[0] == '\r' || pcLine == '\0') {
fprintf(fpDest, "%s", pcLine);
continue;
}
index = 0;
if (!(pcURL_ = get_next_string(",",pcLine,&index,&c))) {
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,"mslplib_Reg: bad file url",SLP_INVALID_REGISTRATION);
}
if (c == '\0' || c == '\n' || c == EOF ||
!(pcLang_ = get_next_string(",",pcLine,&index,&c))) {
if ( pcLang )
{
LOG(SLP_LOG_ERR,"mslplib_Reg: bad lang, use default.");
pcLang_ = safe_malloc(strlen(pcLang)+1,pcLang,strlen(pcLang));
}
}
if (c == '\0' || c == '\n' || c == EOF ||
!(pcTemp_ = get_next_string(",",pcLine,&index,&c))) {
LOG(SLP_LOG_ERR,"mslplib_Reg: bad lifetime - ignore");
}
SLPFree(pcTemp_);
pcTemp_ = NULL;
if (c == '\0' || c == '\n' || c == EOF ||
(pcTemp_ = get_next_string("\000",pcLine,&index,&c)) == NULL) {
int i = 0;
while (pcURL_[i] != '\0' && pcURL_[i] != '/') i++;
if (pcURL_[i] == '\0') {
LOG(SLP_LOG_ERR,"mslplib_Reg: bad service type in URL in file");
err = SLP_INVALID_REGISTRATION;
break;
}
pcSt_ = safe_malloc(i,pcURL_,i-1);
} else {
pcSt_ = pcTemp_;
}
if (!strcmp(pcURL,pcURL_) &&
(!pcLang || !SDstrcasecmp(pcLang,pcLang_))) {
err = SLP_OK;
break;
}
SLPFree(pcSt_); pcSt_ = NULL;
SLPFree(pcURL_); pcURL_ = NULL;
SLPFree(pcLang_); pcLang_ = NULL;
fprintf(fpDest,"%s",pcLine);
while (fgets(pcLine,MAXLINE,fpSrc)) {
char *pcPacked;
fprintf(fpDest,"%s",pcLine);
pcPacked = list_pack(pcLine);
if (pcPacked[0] == '\0') {
SLPFree(pcPacked);
pcPacked = NULL;
break;
}
SLPFree(pcPacked);
pcPacked = NULL;
}
}
SLPFree(pcSt_);
SLPFree(pcURL_);
SLPFree(pcLang_);
return err;
}
static SLPInternalError add_entry(FILE *fpDest, const char *pcURL, const char *pcLang,
unsigned short usLifetime, const char *pcSt) {
if (!pcURL || !fpDest || usLifetime == 0) {
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,"add_entry: missing vital parameters",
SLP_PARAMETER_BAD);
}
if (pcLang == NULL) pcLang = SLPGetProperty("net.slp.locale");
fprintf(fpDest,"%s,%s,%u",pcURL,pcLang,usLifetime);
if (pcSt == NULL || pcSt[0] == '\0') {
fprintf(fpDest,"\n");
} else {
fprintf(fpDest,",%s\n",pcSt);
}
return SLP_OK;
}
void reg_each(const char *pcKey, const char *pcVal, void *pvParam) {
FILE *fpDest = (FILE *) pvParam;
if (pcVal[0] == '\0') {
fprintf(fpDest,"%s\n",pcKey);
} else {
fprintf(fpDest,"%s=%s\n",pcKey,pcVal);
}
}
static SLPInternalError serialize_attributes(FILE *fpDest, MslpHashtable *phash, const char *pcAtt)
{
const char *pcSrc = pcAtt;
char *pcTemp = NULL;
char c;
SLPInternalError err = SLP_OK;
if (!fpDest || !pcAtt)
{
LOG(SLP_LOG_ERR,"serialize_attributes: missing param");
err = SLP_PARAMETER_BAD;
goto serialize_attributes_done;
}
pcTemp = safe_malloc(strlen(pcAtt)+1,pcAtt,strlen(pcAtt));
if (phash == NULL)
{
phash = mslp_hash_init();
}
while (*pcSrc)
{
while (*pcSrc && isspace(*pcSrc))
pcSrc++;
if (*pcSrc == '\0')
{
SLPFree(pcTemp);
pcTemp = NULL;
LOG(SLP_LOG_ERR,"serialize_attributes: empty term!");
err = SLP_INVALID_REGISTRATION;
goto serialize_attributes_done;
}
if (*pcSrc != '(')
{
char *pcDest = pcTemp;
memset(pcTemp,0,strlen(pcAtt));
while (*pcSrc != '\0' && *pcSrc != ',')
{
char c = *pcSrc;
if (c == '(' || c == ')' || c <= 0x20 || c == '=' || c == '!' ||
c == '~' || c == '>' || c == '<' || c == '*' || c == '_' )
{
SLPFree(pcTemp);
pcTemp = NULL;
LOG(SLP_LOG_ERR,"serialize_attributes: bad keyword char");
err = SLP_INVALID_REGISTRATION;
goto serialize_attributes_done;
}
*pcDest++ = *pcSrc++;
}
if ( pcTemp[0] == ',')
{
SLP_LOG( SLP_LOG_DEBUG,"serialize_attributes: empty attr ending with ','");
}
else
{
mslp_hash_add(phash,pcTemp,"");
}
if (*pcSrc == ',')
pcSrc++;
}
else
{
int empty = 1;
char *pcDest = pcTemp;
char *pcKey = NULL;
memset(pcTemp,0,strlen(pcAtt));
pcSrc++;
while (*pcSrc != '\0' && *pcSrc != '=')
{
c = *pcSrc;
if (c == '(' || c == ')' || c < 0x20 || c == '=' || c == '!' ||
c == '~' || c == '>' || c == '<' || c == '*' || c == '_' ||
c == ',' )
{
SLP_LOG(SLP_LOG_ERR,"serialize_attributes: bad tag char: %s", pcTemp);
SLPFree(pcTemp);
pcTemp = NULL;
err = SLP_INVALID_REGISTRATION;
goto serialize_attributes_done;
}
if (!isspace(c))
empty = 0;
*pcDest++ = *pcSrc++;
}
if (*pcSrc == '\0')
{
SLPFree(pcTemp);
pcTemp = NULL;
LOG(SLP_LOG_ERR,"serialize_attributes: unexpected EOL in tag");
err = SLP_INVALID_REGISTRATION;
goto serialize_attributes_done;
}
if (empty || *pcSrc == '\0')
{
SLPFree(pcTemp);
pcTemp = NULL;
LOG(SLP_LOG_ERR,"serialize_attributes: unexpected empty tag");
err = SLP_INVALID_REGISTRATION;
goto serialize_attributes_done;
}
pcKey = safe_malloc(strlen(pcTemp)+1,pcTemp,strlen(pcTemp));
pcDest = pcTemp;
memset(pcTemp,0,strlen(pcAtt));
pcSrc++;
while (*pcSrc != '\0' && *pcSrc != ')')
{
char c = *pcSrc;
if (c == '(' || c == '!' || c == '~' || c == '>' || c == '<' ||
(c < 0x20 && c != 0x0a && c != 0x0d && c != 0x09))
{
SLP_LOG(SLP_LOG_ERR,"serialize_attributes: bad value char: %s", pcTemp);
SLPFree(pcTemp);
pcTemp = NULL;
SLPFree(pcKey);
pcKey = NULL;
err = SLP_INVALID_REGISTRATION;
goto serialize_attributes_done;
}
*pcDest++ = *pcSrc++;
}
if (pcTemp[0] == '\0')
{
SLPFree(pcKey);
pcKey = NULL;
LOG(SLP_LOG_ERR,"serialize_attributes: unexpected omitted val");
err = SLP_INVALID_REGISTRATION;
goto serialize_attributes_done;
}
if (*pcSrc == '\0')
{
SLPFree(pcTemp);
pcTemp = NULL;
SLPFree(pcKey);
pcKey = NULL;
LOG(SLP_LOG_ERR,"serialize_attributes: unexpected EOL in value");
err = SLP_INVALID_REGISTRATION;
goto serialize_attributes_done;
}
pcSrc++;
while (*pcSrc && isspace(*pcSrc))
pcSrc++;
if (pcSrc && *pcSrc == ',')
pcSrc++;
mslp_hash_add(phash,pcKey,pcTemp);
SLPFree(pcKey);
pcKey = NULL;
}
}
mslp_hash_do(phash,reg_each,(void*)fpDest);
serialize_attributes_done:
mslp_hash_free(phash);
SLPFree(pcTemp);
return err;
}
static int scan_till_next_entry(MslpHashtable *phash, FILE *fpSrc) {
char pcLine[MAXLINE];
if (!fpSrc) return (int) SLP_PARAMETER_BAD;
while (fgets(pcLine,MAXLINE,fpSrc)) {
char *pcPacked = list_pack(pcLine);
if (pcPacked[0] == '\0') {
SLPFree(pcPacked);
return 1;
}
SLPFree(pcPacked);
if (phash) {
char *pcTag = NULL;
char *pcVal = NULL;
int index = 0;
char c;
pcTag = get_next_string("=",pcLine,&index,&c);
if (c != '\0') {
pcVal = get_next_string("\000",pcLine, &index,&c);
}
mslp_hash_add(phash,pcTag,(pcVal)?pcVal:"");
SLPFree(pcTag);
SLPFree(pcVal);
}
}
return 0;
}
static void copy_remaining(FILE *fpSrc,FILE *fpDest) {
char pcLine[MAXLINE];
while(fgets(pcLine, MAXLINE, fpSrc)) {
fprintf(fpDest,"%s",pcLine);
}
}
static SLPInternalError mslplib_regipc_rename(const char *pc1, const char *pc2) {
struct stat st1;
char buf[100];
FILE *fpSrc=NULL, *fpDest=NULL;
int total;
if (stat(pc1, &st1) < 0 ||
(fpSrc = fopen(pc1,"rb")) == NULL ||
(fpDest = fopen(pc2,"wb")) == NULL) {
fclose(fpSrc);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,
"mslplib_regipc_rename: open temp file or reg file failed",
SLP_INTERNAL_SYSTEM_ERROR);
} else {
total = st1.st_size;
while (total > 0) {
int xfer = (total > 100) ? 100 : total;
int got;
int wrote;
if ((got = read(fileno(fpSrc),buf,xfer)) != xfer ||
(wrote = write(fileno(fpDest),buf,xfer)) != xfer) {
fclose(fpSrc);
fclose(fpDest);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,
"mslplib_regipc_rename: read temp or write reg file failed",
SLP_INTERNAL_SYSTEM_ERROR);
}
total -= xfer;
}
if (fclose(fpSrc) || fclose(fpDest)) {
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,
"mslplib_regipc_rename: could not close temp or reg file",
SLP_INTERNAL_SYSTEM_ERROR);
}
if (remove(SLPGetProperty("com.sun.slp.tempfile")) < 0) {
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,
"mslplib_regipc_rename: could not remove temp file",
SLP_INTERNAL_SYSTEM_ERROR);
}
}
return SLP_OK;
}
#ifdef READER_TEST
void regipc_copy_till_entry(FILE *fpSrc, FILE *fpDest, const char *pc1,
const char *pc2, const char *pc3) {
copy_till_entry(fpSrc,fpDest,pc1,pc2,pc3);
}
SLPInternalError regipc_add_entry(FILE *fpDest, const char *pcURL,
const char *pcLang, unsigned short usLifetime,
const char *pcSt) {
return add_entry(fpDest,pcURL,pcLang,usLifetime,pcSt);
}
SLPInternalError regipc_serialize_attributes(FILE *fpDest, MslpHashtable *phash,
const char *pcAtt) {
return serialize_attributes(fpDest,phash,pcAtt);
}
int regipc_scan_till_next_entry(MslpHashtable *phash, FILE *fpDest) {
return scan_till_next_entry(phash,fpDest);
}
#endif
#endif