Esempio n. 1
0
/*=========================================================================*/
SLPDDatabaseEntry* SLPDRegFileReadEntry(FILE* fd, SLPDDatabaseEntry** entry)
/* A really big and nasty function that reads an entry SLPDDatabase entry  */
/* from a file. Don't look at this too hard or you'll be sick              */
/*                                                                         */
/* fd       (IN) file to read from                                         */
/*                                                                         */
/* entry    (OUT) Address of a pointer that will be set to the location of */
/*                a dynamically allocated SLPDDatabase entry.  The entry   */
/*                must be freed                                            */
/*                                                                         */
/* Returns  *entry or null on error.                                       */
/*=========================================================================*/
{
    char*   slider1;
    char*   slider2;
    char    line[4096];

    /* give the out param a value */
    *entry = 0;

    /*----------------------------------------------------------*/
    /* read the next non-white non-comment line from the stream */
    /*----------------------------------------------------------*/
    do
    {
        slider1 = RegFileReadLine(fd,line,4096);
        if(slider1 == 0)
        {
            /* read through the whole file and found no entries */
            return 0;
        }
    }while(*slider1 == 0x0d ||  *slider1 == 0x0a);

    /*---------------------------*/
    /* Allocate a database entry */
    /*---------------------------*/
    *entry =  (SLPDDatabaseEntry*)malloc(sizeof(SLPDDatabaseEntry));
    if(entry == 0)
    {
        SLPFatal("Out of memory!\n");
        return 0;
    }
    memset(*entry,0,sizeof(SLPDDatabaseEntry));

    /*---------------------*/
    /* Parse the url-props */
    /*---------------------*/
    slider2 = strchr(slider1,',');
    if(slider2) 
    {
        /* srvurl */
        *slider2 = 0; /* squash comma to null terminate srvurl */
        (*entry)->url = strdup(TrimWhitespace(slider1));
        if((*entry)->url == 0)
        {
            SLPLog("Out of memory reading srvurl from regfile line ->%s",line);
            goto SLPDREGFILEREADENTRY_ERROR1;
        }
        (*entry)->urllen = strlen((*entry)->url);
        
        /* derive srvtype from srvurl if srvurl is "service:" scheme URL */
        if(strncasecmp(slider1,"service:",8)==0) 
        {
            (*entry)->srvtype = strstr(slider1,"://");
            if((*entry)->srvtype == 0)
            {
                SLPLog("Looks like a bad url on regfile line ->%s",line);
                goto SLPDREGFILEREADENTRY_ERROR1;   
            }
            *(*entry)->srvtype = 0;
            (*entry)->srvtype=strdup(TrimWhitespace(slider1));
            (*entry)->srvtypelen = strlen((*entry)->srvtype);
        }
        slider1 = slider2 + 1;

        /*lang*/
        slider2 = strchr(slider1,',');
        if(slider2)
        {
            *slider2 = 0; /* squash comma to null terminate lang */
            (*entry)->langtag = strdup(TrimWhitespace(slider1)); 
            if((*entry)->langtag == 0)
            {
                SLPLog("Out of memory reading langtag from regfile line ->%s",line);
                goto SLPDREGFILEREADENTRY_ERROR1;
            }            (*entry)->langtaglen = strlen((*entry)->langtag);     
            slider1 = slider2 + 1;                                  
        }
        else
        {
            SLPLog("Expected language tag near regfile line ->%s\n",line);
            goto SLPDREGFILEREADENTRY_ERROR1;
        }
             
        /* ltime */
        slider2 = strchr(slider1,',');
        if(slider2)                      
        {
            *slider2 = 0; /* squash comma to null terminate ltime */
            (*entry)->lifetime = atoi(slider1);
            slider1 = slider2 + 1;
        }                                  
        else
        {
            (*entry)->lifetime = atoi(slider1);
            slider1 = slider2;
        }
        if((*entry)->lifetime < 1 || (*entry)->lifetime > 0xffff)
        {
            SLPLog("Invalid lifetime near regfile line ->%s\n",line);
            goto SLPDREGFILEREADENTRY_ERROR1;
        }
        
        /* get the srvtype if one was not derived by the srvurl*/
        if((*entry)->srvtype == 0)
        {
            (*entry)->srvtype = strdup(TrimWhitespace(slider1));
            if((*entry)->srvtype == 0)
            {
                SLPLog("Out of memory reading srvtype from regfile line ->%s",line);
                goto SLPDREGFILEREADENTRY_ERROR1;
            }
            (*entry)->srvtypelen = strlen((*entry)->srvtype);
            if((*entry)->srvtypelen == 0)
            {
                SLPLog("Expected to derive service-type near regfile line -> %s\n",line);
                goto SLPDREGFILEREADENTRY_ERROR1;
            }
        }   

    }
    else
    {
        SLPLog("Expected to find srv-url near regfile line -> %s\n",line);
        goto SLPDREGFILEREADENTRY_ERROR1;
    }
    
    /*-------------------------------------------------*/
    /* Read all the attributes including the scopelist */
    /*-------------------------------------------------*/
    *line=0;
    while(1)
    {
        if(RegFileReadLine(fd,line,4096) == 0)
        {
            break;
        }         
        if(*line == 0x0d || *line == 0x0a)
        {
            break;
        }

        /* Check to see if it is the scopes line */
        if(strncasecmp(line,"scopes",6) == 0)
        {
            /* found scopes line */
            slider1 = line;
            slider2 = strchr(slider1,'=');
            if(slider2)
            {
                slider2++;
                if(*slider2)
                {
                    /* just in case some idiot puts multiple scopes lines */
                    if((*entry)->scopelist)
                    {
                        SLPLog("scopes already defined previous to regfile line ->%s",line);
                        goto SLPDREGFILEREADENTRY_ERROR1;
                    }

                    (*entry)->scopelist=strdup(TrimWhitespace(slider2));
                    if((*entry)->scopelist == 0)
                    {
                        SLPLog("Out of memory adding scopes from regfile line ->%s",line);
                        goto SLPDREGFILEREADENTRY_ERROR1;
                    }
                    (*entry)->scopelistlen = strlen((*entry)->scopelist);
                }
            }
        }
        else
        {
            /* line contains an attribute (slow but it works)*/
            /* TODO Fix this so we do not have to realloc memory each time! */
            TrimWhitespace(line); 
            (*entry)->attrlistlen += strlen(line) + 2;
            
            if((*entry)->attrlist == 0)
            {
                (*entry)->attrlist = malloc((*entry)->attrlistlen + 1);
                *(*entry)->attrlist = 0;
            }
            else
            {
                (*entry)->attrlist = realloc((*entry)->attrlist,
                                             (*entry)->attrlistlen + 1);
            }
            
            if((*entry)->attrlist == 0)
            {
                SLPLog("Out of memory adding DEFAULT scope\n");
                goto SLPDREGFILEREADENTRY_ERROR1;
            }

            strcat((*entry)->attrlist,"(");
            strcat((*entry)->attrlist,line);
            strcat((*entry)->attrlist,")");
        }
    }

    /* Set the scope to default if not is set */
    if((*entry)->scopelist == 0)
    {
        (*entry)->scopelist=strdup("DEFAULT");
        if((*entry)->scopelist == 0)
        {
            SLPLog("Out of memory adding DEFAULT scope\n");
            goto SLPDREGFILEREADENTRY_ERROR1;
        }
        (*entry)->scopelistlen = 7;
    }

    return *entry;

    SLPDREGFILEREADENTRY_ERROR1:
    if(*entry)
    {
        if((*entry)->srvtype) free((*entry)->srvtype);
        if((*entry)->url) free((*entry)->url);
        if((*entry)->langtag) free((*entry)->langtag);
        if((*entry)->scopelist) free((*entry)->scopelist);
        if((*entry)->attrlist) free((*entry)->attrlist);
        free(*entry);
        *entry = 0;
    }

    return 0;
}
Esempio n. 2
0
/*=========================================================================*/
SLPDDatabaseEntry* SLPDRegFileReadEntry(FILE* fd, SLPDDatabaseEntry** entry)
/* A really big and nasty function that reads an entry SLPDDatabase entry  */
/* from a file. Don't look at this too hard or you'll be sick              */
/*                                                                         */
/* fd       (IN) file to read from                                         */
/*                                                                         */
/* entry    (OUT) Address of a pointer that will be set to the location of */
/*                a dynamically allocated SLPDDatabase entry.  The entry   */
/*                must be freed                                            */
/*                                                                         */
/* Returns  *entry or null on error.                                       */
/*=========================================================================*/
{
	char*   slider1;
	char*   slider2;
	char    line[4096];

	/* give the out param a value */
	*entry = 0;

	/*----------------------------------------------------------*/
	/* read the next non-white non-comment line from the stream */
	/*----------------------------------------------------------*/
	do
	{
		slider1 = RegFileReadLine(fd,line,4096);
		if(slider1 == 0)
		{
			/* read through the whole file and found no entries */
			return 0;
		}
	}while(*slider1 == 0x0d ||  *slider1 == 0x0a);

	/*---------------------------*/
	/* Allocate a database entry */
	/*---------------------------*/
	*entry = SLPDDatabaseEntryAlloc();
	if(entry == 0)
	{
		SLPFatal("Out of memory!\n");
		return 0;
	}

	/* entries read from the .reg file are always local */
	(*entry)->islocal = 1;

	/*---------------------*/
	/* Parse the url-props */
	/*---------------------*/
	slider2 = strchr(slider1,',');
	if(slider2)
	{
		/* srvurl */
		*slider2 = 0; /* squash comma to null terminate srvurl */
		(*entry)->url = strdup(TrimWhitespace(slider1));
		if((*entry)->url == 0)
		{
			SLPLog("Out of memory reading srvurl from regfile line ->%s",line);
			goto SLPD_ERROR;
		}
		(*entry)->urllen = strlen((*entry)->url);

		/* derive srvtype from srvurl */
		(*entry)->srvtype = strstr(slider1,"://");
		if((*entry)->srvtype == 0)
		{
			SLPLog("Looks like a bad url on regfile line ->%s",line);
			goto SLPD_ERROR;   
		}
		*(*entry)->srvtype = 0;
		(*entry)->srvtype=strdup(TrimWhitespace(slider1));
		(*entry)->srvtypelen = strlen((*entry)->srvtype);
		slider1 = slider2 + 1;

		/*lang*/
		slider2 = strchr(slider1,',');
		if(slider2)
		{
			*slider2 = 0; /* squash comma to null terminate lang */
			(*entry)->langtag = strdup(TrimWhitespace(slider1)); 
			if((*entry)->langtag == 0)
			{
				SLPLog("Out of memory reading langtag from regfile line ->%s",line);
				goto SLPD_ERROR;
			}(*entry)->langtaglen = strlen((*entry)->langtag);     
			slider1 = slider2 + 1;                                  
		}
		else
		{
			SLPLog("Expected language tag near regfile line ->%s\n",line);
			goto SLPD_ERROR;
		}

		/* ltime */
		slider2 = strchr(slider1,',');
		if(slider2)
		{
			*slider2 = 0; /* squash comma to null terminate ltime */
			(*entry)->lifetime = atoi(slider1);
			slider1 = slider2 + 1;
		}
		else
		{
			(*entry)->lifetime = atoi(slider1);
			slider1 = slider2;
		}
		if((*entry)->lifetime < 1 || (*entry)->lifetime > 0xffff)
		{
			SLPLog("Invalid lifetime near regfile line ->%s\n",line);
			goto SLPD_ERROR;
		}

		/* get the srvtype if one was not derived by the srvurl*/
		if((*entry)->srvtype == 0)
		{
			(*entry)->srvtype = strdup(TrimWhitespace(slider1));
			if((*entry)->srvtype == 0)
			{
				SLPLog("Out of memory reading srvtype from regfile line ->%s",line);
				goto SLPD_ERROR;
			}
			(*entry)->srvtypelen = strlen((*entry)->srvtype);
			if((*entry)->srvtypelen == 0)
			{
				SLPLog("Expected to derive service-type near regfile line -> %s\n",line);
				goto SLPD_ERROR;
			}
		}
	}
	else
	{
		SLPLog("Expected to find srv-url near regfile line -> %s\n",line);
		goto SLPD_ERROR;
	}

	/*-------------------------------------------------*/
	/* Read all the attributes including the scopelist */
	/*-------------------------------------------------*/
	*line=0;
	while(1)
	{
		if(RegFileReadLine(fd,line,4096) == 0)
		{
			break;
		}
		if(*line == 0x0d || *line == 0x0a)
		{
			break;
		}

		/* Check to see if it is the scopes line */
		/* FIXME We can collapse the scope stuff into the value getting and 
		 * just make it a special case (do strcmp on the tag as opposed to the 
		 * line) of attribute getting. 
		 */
		if(strncasecmp(line,"scopes",6) == 0)
		{
			/* found scopes line */
			slider1 = line;
			slider2 = strchr(slider1,'=');
			if(slider2)
			{
				slider2++;
				if(*slider2)
				{
					/* just in case some idiot puts multiple scopes lines */
					if((*entry)->scopelist)
					{
						SLPLog("scopes already defined previous to regfile line ->%s",line);
						goto SLPD_ERROR;
					}

					(*entry)->scopelist=strdup(TrimWhitespace(slider2));
					if((*entry)->scopelist == 0)
					{
						SLPLog("Out of memory adding scopes from regfile line ->%s",line);
						goto SLPD_ERROR;
					}
					(*entry)->scopelistlen = strlen((*entry)->scopelist);
				}
			}
		}
		else
		{
#ifdef USE_PREDICATES
			char *tag; /* Will point to the start of the tag. */
			char *val; /* Will point to the start of the value. */
			char *end;
			char *tag_end;

			tag = line;
			/*** Elide ws. ***/
			while(isspace(*tag))
			{
				tag++;
			}
			tag_end = tag;

			/*** Find tag end. ***/
			while(*tag_end && (!isspace(*tag_end)) && (*tag_end != '='))
			{
				tag_end++;
			}
			while(*tag_end && *tag_end != '=')
			{
				tag_end++;
			}
			*tag_end = 0;

			/*** Find value start. ***/
			val = tag_end + 1;
			/*** Elide ws. ***/
			while(isspace(*val))
			{
				val++;
			}

			/*** Elide trailing ws. ***/
			end = val;

			/** Find tag end. **/
			while(*end != 0)
			{
				end++;
			}

			/*** Back up over trailing whitespace. ***/
			end--;
			while(isspace(*end))
			{
				*end = 0; /* Overwrite ws. */
				end--;
			}           

			SLPAttrSet_guess((*entry)->attr, tag, val, SLP_ADD);

#else


			/* line contains an attribute (slow but it works)*/
			/* TODO Fix this so we do not have to realloc memory each time! */
			TrimWhitespace(line); 
			(*entry)->attrlistlen += strlen(line) + 2;

			if((*entry)->attrlist == 0)
			{
				(*entry)->attrlist = malloc((*entry)->attrlistlen + 1);
				*(*entry)->attrlist = 0;
			}
			else
			{
				(*entry)->attrlist = realloc((*entry)->attrlist,
											 (*entry)->attrlistlen + 2);
				strcat((*entry)->attrlist,",");
			}

			if((*entry)->attrlist == 0)
			{
				SLPLog("Out of memory adding DEFAULT scope\n");
				goto SLPD_ERROR;
			}

			strcat((*entry)->attrlist,"(");
			strcat((*entry)->attrlist,line);
			strcat((*entry)->attrlist,")");

#endif
		}
	}

	/* Set the scope set in properties if not is set */
	if((*entry)->scopelist == 0)
	{
		(*entry)->scopelist=strdup(G_SlpdProperty.useScopes);
		if((*entry)->scopelist == 0)
		{
			SLPLog("Out of memory adding DEFAULT scope\n");
			goto SLPD_ERROR;
		}
		(*entry)->scopelistlen = G_SlpdProperty.useScopesLen;
	}

	return *entry;

	SLPD_ERROR:
	if(*entry)
	{
		SLPDDatabaseEntryFree(*entry);
		*entry = 0;
	}

	return 0;
}
Esempio n. 3
0
/** Read service registrations from a text file.
 *
 * A really big and nasty function that reads service registrations from
 * from a file. Don't look at this too hard or you'll be sick. This is by
 * far the most horrible code in OpenSLP. Please volunteer to rewrite it!
 *
 * "THANK GOODNESS this function is only called at startup" -- Matt
 *
 * @param[in] fd - The file to read from.
 * @param[out] msg - A message describing the SrvReg in buf.
 * @param[out] buf - The buffer used to hold @p message data.
 *
 * @return Zero on success. A value greater than zero on error. A value
 *    less than zero on EOF.
 *
 * @note Eventually the caller needs to call SLPBufferFree and
 *    SLPMessageFree to free memory.
 */
int SLPDRegFileReadSrvReg(FILE * fd, SLPMessage ** msg, SLPBuffer * buf)
{
   char * slider1;
   char * slider2;
   char line[4096];

   struct sockaddr_storage peer;
   int result = 0;
   size_t bufsize = 0;
   size_t langtaglen = 0;
   char * langtag = 0;
   size_t scopelistlen = 0;
   char * scopelist = 0;
   size_t urllen = 0;
   char * url = 0;
   int lifetime = 0;
   size_t srvtypelen = 0;
   char * srvtype = 0;
   size_t attrlistlen = 0;
   char * attrlist = 0;
   SLPBuffer tmp;

#ifdef ENABLE_SLPv2_SECURITY
   unsigned char * urlauth = 0;
   int urlauthlen = 0;
   unsigned char * attrauth = 0;
   int attrauthlen = 0;
#endif

   /* give the out params an initial NULL value */
   *buf = 0;
   *msg = 0;

   /* read the next non-white non-comment line from the stream */
   do
   {
      slider1 = RegFileReadLine(fd, line, 4096);
      if (slider1 == 0)
         return -1;

   } while (*slider1 == 0x0d ||  *slider1 == 0x0a);

   /* Parse the url-props */
   slider2 = strchr(slider1, ',');
   if (slider2)
   {
      /* srvurl */
      *slider2 = 0; /* squash comma to null terminate srvurl */
      url = xstrdup(TrimWhitespace(slider1));
      if (url == 0)
      {
         result = SLP_ERROR_INTERNAL_ERROR;
         goto CLEANUP;
      }
      urllen = strlen(url);

      /* derive srvtype from srvurl */
      srvtype = strstr(slider1, "://");
      if (srvtype == 0)
      {
         result = SLP_ERROR_INVALID_REGISTRATION;
         goto CLEANUP;
      }
      *srvtype = 0;
      srvtype=xstrdup(TrimWhitespace(slider1));
      if (srvtype == 0)
      {
         result = SLP_ERROR_INTERNAL_ERROR;
         goto CLEANUP;
      }
      srvtypelen = strlen(srvtype);
      slider1 = slider2 + 1;

      /*lang*/
      slider2 = strchr(slider1, ',');
      if (slider2)
      {
         *slider2 = 0; /* squash comma to null terminate lang */
         langtag = xstrdup(TrimWhitespace(slider1));
         if (langtag == 0)
         {
            result = SLP_ERROR_INVALID_REGISTRATION;
            goto CLEANUP;
         }
         langtaglen = strlen(langtag);
         slider1 = slider2 + 1;
      }
      else
      {
         result = SLP_ERROR_INVALID_REGISTRATION;
         goto CLEANUP;
      }

      /* ltime */
      slider2 = strchr(slider1,',');
      if (slider2)
      {
         *slider2 = 0; /* squash comma to null terminate ltime */
         lifetime = atoi(slider1);
         slider1 = slider2 + 1;
      }
      else
      {
         lifetime = atoi(slider1);
         slider1 = slider2;
      }
      if (lifetime < 1 || lifetime > SLP_LIFETIME_MAXIMUM)
      {
         result = SLP_ERROR_INVALID_REGISTRATION;
         goto CLEANUP;
      }

      /* get the srvtype if one was not derived by the srvurl */
      if (srvtype == 0)
      {
         srvtype = xstrdup(TrimWhitespace(slider1));
         if (srvtype == 0)
         {
            result = SLP_ERROR_INTERNAL_ERROR;
            goto CLEANUP;
         }
         srvtypelen = strlen(srvtype);
         if (srvtypelen == 0)
         {
            result = SLP_ERROR_INVALID_REGISTRATION;
            goto CLEANUP;
         }
      }
   }
   else
   {
      result = SLP_ERROR_INVALID_REGISTRATION;
      goto CLEANUP;
   }

   /* read all the attributes including the scopelist */
   *line=0;
   while (1)
   {
      slider1 = RegFileReadLine(fd,line,4096);
      if (slider1 == 0)
      {
         result = -1;
         break;
      }
      if (*slider1 == 0x0d || *slider1 == 0x0a)
         break;

      /* Check to see if it is the scopes line */
      /* FIXME We can collapse the scope stuff into the value getting and
         just make it a special case (do strcmp on the tag as opposed to the
         line) of attribute getting. */
      if (strncasecmp(slider1,"scopes", 6) == 0)
      {
         /* found scopes line */
         slider2 = strchr(slider1,'=');
         if (slider2)
         {
            slider2++;
            if (*slider2)
            {
               /* just in case some idiot puts multiple scopes lines */
               if (scopelist)
               {
                  result = SLP_ERROR_SCOPE_NOT_SUPPORTED;
                  goto CLEANUP;
               }

               /* make sure there are no spaces in the scope list
      NOTE: There's nothing in the spec that indicates that
      scopes can't contain spaces. Commenting out for now. --jmc
               if (strchr(slider2, ' '))
               {
                  result = SLP_ERROR_SCOPE_NOT_SUPPORTED;
                  goto CLEANUP;
               } */

               scopelist = xstrdup(TrimWhitespace(slider2));
               if (scopelist == 0)
               {
                  result = SLP_ERROR_INTERNAL_ERROR;
                  goto CLEANUP;
               }
               scopelistlen = strlen(scopelist);
            }
         }
      }
      else
      {
         /* line contains an attribute (slow but it works)*/
         /* TODO Fix this so we do not have to realloc memory each time! */
         TrimWhitespace(slider1);

         if (attrlist == 0)
         {
            attrlistlen += strlen(slider1) + 2;
            attrlist = xmalloc(attrlistlen + 1);
            if (attrlist == 0)
            {
               result = SLP_ERROR_INTERNAL_ERROR;
               goto CLEANUP;
            }
            *attrlist = 0;
         }
         else
         {
            char * tmp_attrlist;
            attrlistlen += strlen(slider1) + 3;
            if ((tmp_attrlist = xrealloc(attrlist, attrlistlen + 1)) == 0)
            {
               xfree(attrlist);
               result = SLP_ERROR_INTERNAL_ERROR;
               goto CLEANUP;
            }
            attrlist = tmp_attrlist;
            strcat(attrlist, ",");
         }

         if (attrlist == 0)
         {
            result = SLP_ERROR_INTERNAL_ERROR;
            goto CLEANUP;
         }

         /* we need special case for keywords (why do we need these)
            they seem like a waste of code.  Why not just use booleans */
         if (strchr(slider1, '='))
         {
            /* normal attribute (with '=') */
            strcat(attrlist, "(");
            strcat(attrlist, slider1);
            strcat(attrlist, ")");
         }
         else
         {
            /* keyword (no '=') */
            attrlistlen -= 2; /* subtract 2 bytes for no '(' or ')' */
            strcat(attrlist, slider1);
         }
      }
   }

   /* Set the scope set in properties if not is set */
   if (scopelist == 0)
   {
      scopelist = xstrdup(G_SlpdProperty.useScopes);
      if (scopelist == 0)
      {
         result = SLP_ERROR_INTERNAL_ERROR;
         goto CLEANUP;
      }
      scopelistlen = G_SlpdProperty.useScopesLen;
   }

#ifdef ENABLE_SLPv2_SECURITY
   /* generate authentication blocks */
   if (G_SlpdProperty.securityEnabled)
   {
      SLPAuthSignUrl(G_SlpdSpiHandle, 0, 0, urllen, url,
            &urlauthlen, &urlauth);
      SLPAuthSignString(G_SlpdSpiHandle, 0, 0, attrlistlen, attrlist,
            &attrauthlen, &attrauth);
   }
#endif

   /* allocate buffer for the SrvReg Message */
   bufsize = 14 + langtaglen;    /* 14 bytes for header    */
   bufsize += urllen + 6;        /*  1 byte for reserved   */
                                 /*  2 bytes for lifetime  */
                                 /*  2 bytes for urllen    */
                                 /*  1 byte for authcount  */
   bufsize += srvtypelen + 2;    /*  2 bytes for len field */
   bufsize += scopelistlen + 2;  /*  2 bytes for len field */
   bufsize += attrlistlen + 2;   /*  2 bytes for len field */
   bufsize += 1;                 /*  1 byte for authcount  */

#ifdef ENABLE_SLPv2_SECURITY
   bufsize += urlauthlen;
   bufsize += attrauthlen;
#endif

   tmp = *buf = SLPBufferAlloc(bufsize);
   if (tmp == 0)
   {
      result = SLP_ERROR_INTERNAL_ERROR;
      goto CLEANUP;
   }

   /* now build the SrvReg Message */

   /* version */
   *tmp->curpos++ = 2;

   /* function id */
   *tmp->curpos++ = SLP_FUNCT_SRVREG;

   /* length */
   PutUINT24(&tmp->curpos, bufsize);

   /* flags */
   PutUINT16(&tmp->curpos, 0);

   /* ext offset */
   PutUINT24(&tmp->curpos, 0);

   /* xid */
   PutUINT16(&tmp->curpos, 0);

   /* lang tag len */
   PutUINT16(&tmp->curpos, langtaglen);

   /* lang tag */
   memcpy(tmp->curpos, langtag, langtaglen);
   tmp->curpos += langtaglen;

   /* url-entry reserved */
   *tmp->curpos++ = 0;

   /* url-entry lifetime */
   PutUINT16(&tmp->curpos, lifetime);

   /* url-entry urllen */
   PutUINT16(&tmp->curpos, urllen);

   /* url-entry url */
   memcpy(tmp->curpos, url, urllen);
   tmp->curpos += urllen;

   /* url-entry authblock */
#ifdef ENABLE_SLPv2_SECURITY
   if (urlauth)
   {
      /* authcount */
      *tmp->curpos++ = 1;

      /* authblock */
      memcpy(tmp->curpos, urlauth, urlauthlen);
      tmp->curpos += urlauthlen;
   }
   else
#endif
      *tmp->curpos++ = 0;

   /* service type */
   PutUINT16(&tmp->curpos, srvtypelen);
   memcpy(tmp->curpos, srvtype, srvtypelen);
   tmp->curpos += srvtypelen;

   /* scope list */
   PutUINT16(&tmp->curpos, scopelistlen);
   memcpy(tmp->curpos, scopelist, scopelistlen);
   tmp->curpos += scopelistlen;

   /* attr list */
   PutUINT16(&tmp->curpos, attrlistlen);
   memcpy(tmp->curpos, attrlist, attrlistlen);
   tmp->curpos += attrlistlen;

   /* attribute auth block */
#ifdef ENABLE_SLPv2_SECURITY
   if (attrauth)
   {
      /* authcount */
      *tmp->curpos++ = 1;

      /* authblock */
      memcpy(tmp->curpos, attrauth, attrauthlen);
      tmp->curpos += attrauthlen;
   }
   else
#endif
      *tmp->curpos++ = 0;

   /* okay, now comes the really stupid (and lazy part) */
   *msg = SLPMessageAlloc();
   if (*msg == 0)
   {
      SLPBufferFree(*buf);
      *buf = 0;
      result = SLP_ERROR_INTERNAL_ERROR;
      goto CLEANUP;
   }

   /* this should be ok even if we are not supporting IPv4,
    * since it's a static service
    */
   memset(&peer, 0, sizeof(struct sockaddr_in));
   peer.ss_family = AF_UNSPEC;
   ((struct sockaddr_in *)&peer)->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
   result = SLPMessageParseBuffer(&peer, &peer, *buf, *msg);
   (*msg)->body.srvreg.source = SLP_REG_SOURCE_STATIC;

CLEANUP:

   /* check for errors and free memory */
   switch(result)
   {
      case SLP_ERROR_INTERNAL_ERROR:
         SLPDLog("\nERROR: Out of memory one reg file line:\n   %s\n", line);
         break;

      case SLP_ERROR_INVALID_REGISTRATION:
         SLPDLog("\nERROR: Invalid reg file format near:\n   %s\n", line);
         break;

      case SLP_ERROR_SCOPE_NOT_SUPPORTED:
         SLPDLog("\nERROR: Duplicate scopes or scope list with "
               "embedded spaces near:\n   %s\n", line);
         break;

      default:
         break;
   }

   xfree(langtag);
   xfree(scopelist);
   xfree(url);
   xfree(srvtype);
   xfree(attrlist);

#ifdef ENABLE_SLPv2_SECURITY
   xfree(urlauth);
   xfree(attrauth);
#endif

   return result;
}