Exemple #1
0
void __cdecl main(int argc, char **argv) 
{
    SERVICE_TABLE_ENTRY dispatchTable[] = 
    { 
        { G_SERVICENAME, (LPSERVICE_MAIN_FUNCTION)SLPDServiceMain}, 
        { NULL, NULL} 
    }; 

    /*------------------------*/
    /* Parse the command line */
    /*------------------------*/
    if(SLPDParseCommandLine(argc,argv))
    {
        SLPFatal("Invalid command line\n");
    }

    switch(G_SlpdCommandLine.action)
    {
    case SLPD_DEBUG:
        SLPDCmdDebugService(argc, argv);
        break;
    case SLPD_INSTALL:
        SLPDCmdInstallService();
        break;
    case SLPD_REMOVE:
        SLPDCmdRemoveService();
        break;
    default:
        SLPDPrintUsage();
        StartServiceCtrlDispatcher(dispatchTable);

        break;
    } 
} 
Exemple #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;
}
Exemple #3
0
/*=========================================================================*/
int main(int argc, char* argv[])
/*=========================================================================*/
{
    fd_set          readfds;
    fd_set          writefds;
    int             highfd;
    int             fdcount         = 0;

    /*------------------------*/
    /* Parse the command line */
    /*------------------------*/
    if(SLPDParseCommandLine(argc,argv))
    {
        SLPFatal("Invalid command line\n");
    }

    /*------------------------------*/
    /* Make sure we are root        */
    /*------------------------------*/
    if(getuid() != 0)
    {
        SLPFatal("slpd must be started by root\n");
    }

    /*--------------------------------------*/
    /* Make sure we are not already running */
    /*--------------------------------------*/
    if(CheckPid(G_SlpdCommandLine.pidfile))
    {
        SLPFatal("slpd is already running. Check %s\n",
                 G_SlpdCommandLine.pidfile);
    }

    /*------------------------------*/
    /* Initialize the log file      */
    /*------------------------------*/
    if(SLPLogFileOpen(G_SlpdCommandLine.logfile, 1))
    {
        SLPFatal("Could not open logfile %s\n",G_SlpdCommandLine.logfile);
    }

    /*------------------------*/
    /* Seed the XID generator */
    /*------------------------*/
    SLPXidSeed();

    /*---------------------*/
    /* Log startup message */
    /*---------------------*/
    SLPLog("****************************************\n");
    SLPLogTime();
    SLPLog("SLPD daemon started\n");
    SLPLog("****************************************\n");
    SLPLog("Command line = %s\n",argv[0]);
    SLPLog("Using configuration file = %s\n",G_SlpdCommandLine.cfgfile);
    SLPLog("Using registration file = %s\n",G_SlpdCommandLine.regfile);

    /*--------------------------------------------------*/
    /* Initialize for the first time                    */
    /*--------------------------------------------------*/
    if(SLPDPropertyInit(G_SlpdCommandLine.cfgfile) ||
       SLPDDatabaseInit(G_SlpdCommandLine.regfile) ||
       SLPDIncomingInit() ||
       SLPDOutgoingInit() ||
       SLPDKnownDAInit())
    {
        SLPFatal("slpd initialization failed\n");
    }
    SLPLog("Agent Interfaces = %s\n",G_SlpdProperty.interfaces);
    SLPLog("Agent URL = %s\n",G_SlpdProperty.myUrl);

    /*---------------------------*/
    /* make slpd run as a daemon */
    /*---------------------------*/
    if(Daemonize(G_SlpdCommandLine.pidfile))
    {
        SLPFatal("Could not daemonize\n");
    }

    /*-----------------------*/
    /* Setup signal handlers */
    /*-----------------------*/
    if(SetUpSignalHandlers())
    {
        SLPFatal("Error setting up signal handlers.\n");
    }

    /*------------------------------*/
    /* Set up alarm to age database */
    /*------------------------------*/
    alarm(SLPD_AGE_INTERVAL);

    /*-----------*/
    /* Main loop */
    /*-----------*/
    SLPLog("Startup complete entering main run loop ...\n\n");
    G_SIGALRM   = 0;
    G_SIGTERM   = 0;
    G_SIGHUP    = 0;    
    while(G_SIGTERM == 0)
    {
        /*--------------------------------------------------------*/
        /* Load the fdsets up with all valid sockets in the list  */
        /*--------------------------------------------------------*/
        highfd = 0;
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);
        LoadFdSets(&G_IncomingSocketList, &highfd, &readfds,&writefds);
        LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds);

        /*--------------------------------------------------*/
        /* Before select(), check to see if we got a signal */
        /*--------------------------------------------------*/
        if(G_SIGALRM || G_SIGHUP)
        {
            goto HANDLE_SIGNAL;
        }

        /*-------------*/
        /* Main select */
        /*-------------*/
        fdcount = select(highfd+1,&readfds,&writefds,0,0);
        if(fdcount > 0) /* fdcount will be < 0 when interrupted by a signal */
        {
            SLPDIncomingHandler(&fdcount,&readfds,&writefds);
            SLPDOutgoingHandler(&fdcount,&readfds,&writefds);
        }

        /*----------------*/
        /* Handle signals */
        /*----------------*/
        HANDLE_SIGNAL:
        if(G_SIGHUP)
        {
            HandleSigHup();
            G_SIGHUP = 0;
        }
        if(G_SIGALRM)
        {
            HandleSigAlrm();
            G_SIGALRM = 0;
            alarm(SLPD_AGE_INTERVAL);
        }

    } /* End of main loop */

    /* Got SIGTERM */
    HandleSigTerm();

    return 0;
}
Exemple #4
0
/*=========================================================================*/
int main(int argc, char* argv[])
/*=========================================================================*/
{
    fd_set          readfds;
    fd_set          writefds;
    int             highfd;
    int             fdcount         = 0;
    
    /*------------------------------*/
    /* Make sure we are root        */
    /*------------------------------*/
    if(getuid() != 0)
    {
        SLPFatal("slpd must be started by root\n");
    }
     
    
    /*------------------------*/
    /* Parse the command line */
    /*------------------------*/
    if(SLPDParseCommandLine(argc,argv))
    {
        SLPFatal("Invalid command line\n");
    }

    
    /*------------------------------*/
    /* Initialize the log file      */
    /*------------------------------*/
    SLPLogFileOpen(G_SlpdCommandLine.logfile, 0);
    SLPLog("****************************************\n");
    SLPLog("*** SLPD daemon started              ***\n");
    SLPLog("****************************************\n");
    SLPLog("command line = %s\n",argv[0]);
    
    
    /*--------------------------------------------------*/
    /* Initialize for the first time                    */
    /*--------------------------------------------------*/
    SLPDPropertyInit(G_SlpdCommandLine.cfgfile);
    SLPDDatabaseInit(G_SlpdCommandLine.regfile);
    SLPDIncomingInit();
    SLPDOutgoingInit();
    SLPDKnownDAInit();
    /* TODO: Check error codes on all init functions */
    
    /*---------------------------*/
    /* make slpd run as a daemon */
    /*---------------------------*/
    if(Daemonize(G_SlpdCommandLine.pidfile))
    {
        SLPFatal("Could not run as daemon\n");
    }

    /*-----------------------*/
    /* Setup signal handlers */ 
    /*-----------------------*/
    if(SetUpSignalHandlers())
    {
        SLPFatal("Could not set up signal handlers.\n");
    }
    
    /*------------------------------*/
    /* Set up alarm to age database */
    /*------------------------------*/
    alarm(SLPD_AGE_INTERVAL);

    /*-----------*/
    /* Main loop */
    /*-----------*/
    G_SIGALRM   = 0;
    G_SIGTERM   = 0;
    G_SIGHUP    = 0;    
	SLPLog("Initialization complete\n\n");
    while(G_SIGTERM == 0)
    {
        /*--------------------------------------------------------*/
        /* Load the fdsets up with all valid sockets in the list  */
        /*--------------------------------------------------------*/
        highfd = 0;
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);
        LoadFdSets(&G_IncomingSocketList, &highfd, &readfds,&writefds);
        LoadFdSets(&G_OutgoingSocketList, &highfd, &readfds,&writefds);
        
        /*--------------------------------------------------*/
        /* Before select(), check to see if we got a signal */
        /*--------------------------------------------------*/
        if(G_SIGALRM || G_SIGHUP)
        {
            goto HANDLE_SIGNAL;
        }
        
        /*-------------*/
        /* Main select */
        /*-------------*/
        fdcount = select(highfd+1,&readfds,&writefds,0,0);
        if(fdcount > 0) /* fdcount will be < 0 when interrupted by a signal */
        {
            SLPDIncomingHandler(&fdcount,&readfds,&writefds);
            SLPDOutgoingHandler(&fdcount,&readfds,&writefds);
        }

        /*----------------*/
        /* Handle signals */
        /*----------------*/
HANDLE_SIGNAL:
        if(G_SIGHUP)
        {
            /* Reinitialize */
            SLPLog("****************************************\n");
            SLPLog("*** SLPD daemon restarted            ***\n");
            SLPLog("****************************************\n");
            SLPLog("Got SIGHUP reinitializing... \n");
        
            SLPDPropertyInit(G_SlpdCommandLine.cfgfile);
            SLPDDatabaseInit(G_SlpdCommandLine.regfile);
            /* Don't reinitialize Incoming because we can't rebind to */
            /* slp reserved port because we are not root now          */
            /* SLPDIncomingInit(); */
            SLPDOutgoingInit();
            SLPDKnownDAInit();
            G_SIGHUP = 0;     
        } 
        if(G_SIGALRM)
        {
            /* TODO: add call to do passive DAAdvert */
            SLPDIncomingAge(SLPD_AGE_INTERVAL);
            SLPDOutgoingAge(SLPD_AGE_INTERVAL);
            SLPDDatabaseAge(SLPD_AGE_INTERVAL);
            SLPDKnownDAActiveDiscovery();
            G_SIGALRM = 0;
            alarm(SLPD_AGE_INTERVAL);
        }
                            

    } /* End of main loop */

    SLPLog("Got SIGTERM.  Going down\n");

    #if(defined DEBUG)
    SLPDIncomingDeinit();
    SLPDOutgoingDeinit();
    printf("Number of calls to SLPBufferAlloc() = %i\n",G_Debug_SLPBufferAllocCount);
    printf("Number of calls to SLPBufferFree() = %i\n",G_Debug_SLPBufferFreeCount);
    #endif
    return 0;
}
Exemple #5
0
/*-------------------------------------------------------------------------*/
int Daemonize(const char* pidfile)
/* Turn the calling process into a daemon (detach from tty setuid(), etc   */
/*                                                                         */      
/* Returns: zero on success non-zero if slpd could not daemonize (or if    */
/*          slpd is already running                             .          */
/*-------------------------------------------------------------------------*/
{
    pid_t   pid;
    FILE*   fd;
    struct  passwd* pwent;
    char    pidstr[13];
    
    if(G_SlpdCommandLine.detach)
    {
    
        /*-------------------------------------------*/
        /* Release the controlling tty and std files */
        /*-------------------------------------------*/
        switch(fork())
        {
        case -1:
            return -1;
        case 0:
            /* child lives */
            break;
    
        default:
            /* parent dies */
            exit(0);
        }
    
        close(0); 
        close(1); 
        close(2); 
        setsid(); /* will only fail if we are already the process group leader */
    }
     
    /*------------------------------------------*/
    /* make sure that we're not running already */
    /*------------------------------------------*/
    /* read the pid from the file */
    fd = fopen(pidfile,"r");
    if(fd)
    {
        fread(pidstr,13,1,fd);
        fclose(fd);
        pid = atoi(pidstr);
        if(pid)
        {
            if(kill(pid,0) == 0)
            {
                /* we are already running */
                SLPFatal("slpd daemon is already running\n");
                return -1;
            }
        }    
    }
    /* write my pid to the pidfile */
    fd = fopen(pidfile,"w");
    if(fd)
    {
        sprintf(pidstr,"%i",getpid());
        fwrite(pidstr,strlen(pidstr),1,fd);
        fclose(fd);
    }
    
    /*----------------*/
    /* suid to daemon */
    /*----------------*/
    /* TODO: why do the following lines mess up my signal handlers? */
    pwent = getpwnam("daemon"); 
    if(pwent)
    {
        if( setgroups(1, &pwent->pw_gid) < 0 ||
            setgid(pwent->pw_gid) < 0 ||
            setuid(pwent->pw_uid) < 0 )
        {
            /* TODO: should we log here and return fail */
        }
    }
    
    return 0;
}
Exemple #6
0
/*=========================================================================*/
void SLPDSocketInit(SLPDSocketList* list)
/* Adds SLPSockets (UDP and TCP) for all the interfaces and the loopback   */
/*                                                                         */
/* list     - pointer to SLPSocketList to initialize                       */
/*                                                                         */
/* Returns  - zero on success, -1 on failure.                              */
/*=========================================================================*/
{
    char*           begin;
    char*           end;
    int             finished;
    struct in_addr  myaddr;
    struct in_addr  mcastaddr;
    struct in_addr  bcastaddr;
    SLPDSocket*     sock;

    /*----------------------------------------------------*/
    /* Decide what address to use for multicast/broadcast */
    /*----------------------------------------------------*/
    mcastaddr.s_addr = htonl(SLP_MCAST_ADDRESS);
    bcastaddr.s_addr = htonl(0xffffffff);     

    

    /*-----------------------------------------------------------------*/
    /* Create SOCKET_LISTEN socket for LOOPBACK for the library to talk to*/
    /*-----------------------------------------------------------------*/
    sock = (SLPDSocket*)malloc(sizeof(SLPDSocket));
    if(sock == 0)
    {
        return;
    }
    memset(sock,0,sizeof(SLPDSocket));

    sock->fd = socket(PF_INET, SOCK_STREAM, 0);
    if(sock->fd >= 0)
    {          
        if(BindSocketToLoopback(sock->fd) >= 0)
        {
            if(listen(sock->fd,5) == 0)
            {
                sock->state = SOCKET_LISTEN;
                if(SLPDSocketListAdd(list,sock) == 0)
                {
                    SLPFatal("Out of memory");
                }

                SLPLog("SLPLIB API socket listening\n");
            }
            else
            {
                /* could not listen(), close the socket*/
                close(sock->fd);
                free(sock);
                SLPLog("ERROR: Could not listen on loopback\n");
                SLPLog("ERROR: No SLPLIB support will be available\n");
            }
        }
        else
        {
            /* could not bind, close the socket*/
            close(sock->fd);
            free(sock);
            SLPLog("ERROR: Could not bind loopback port 427.\n");
            SLPLog("ERROR: slpd may already be running\n");
        }
    }
    else
    {
        /* could not create the socket */
        free(sock);
        SLPLog("ERROR: Could not create socket for loopback.\n");
        SLPLog("ERROR: No SLPLIB support will be available\n");
    }

                                                                                   
    /*---------------------------------------------------------------------*/
    /* Create sockets for all of the interfaces in the interfaces property */
    /*---------------------------------------------------------------------*/
    begin = (char*)G_SlpdProperty.interfaces;
    end = begin;
    finished = 0;
    while( finished == 0)
    {
        while(*end && *end != ',') end ++;
        if(*end == 0) finished = 1;
        while(*end <=0x2f) 
        {
            *end = 0;
            end--;
        }

        /* begin now points to a null terminated ip address string */
        myaddr.s_addr = inet_addr(begin);

        /*--------------------------------------------------------*/
        /* Create socket that will handle multicast UDP           */
        /*--------------------------------------------------------*/
    
        sock = (SLPDSocket*)malloc(sizeof(SLPDSocket));
        if(sock == 0)
        {
            break;
        }
        sock->fd = socket(PF_INET, SOCK_DGRAM, 0);
        if(sock->fd >=0)
        {
            if(BindSocketToInetAddr(sock->fd, &mcastaddr) >= 0)
            {
                if(JoinSLPMulticastGroup(sock->fd, &myaddr) == 0)
                {
                    sock->state = DATAGRAM_MULTICAST;
                    sock->recvbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE);  
                    sock->sendbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE);
                    sock->peerinfo.peeraddrlen = sizeof(sock->peerinfo.peeraddr);
                    sock->peerinfo.peertype = SLPD_PEER_REMOTE; 
                    if(sock->recvbuf == 0 || sock->sendbuf == 0)
                    {
                        SLPFatal("SLPD out of memory !!\n");
                    }
                    SLPDSocketListAdd(list,sock);
                    SLPLog("Multicast socket on %s ready\n",inet_ntoa(myaddr));
                }
                else
                {
                    /* could not add multicast membership */
                    close(sock->fd);
                    free(sock);
                }
            }
            else
            {
                /* could not bind(), close the socket*/
                close(sock->fd);
                free(sock);
            }
        }

        /*--------------------------------------------*/
        /* Create socket that will handle unicast UDP */
        /*--------------------------------------------*/
        sock = (SLPDSocket*)malloc(sizeof(SLPDSocket));
        if(sock == 0)
        {
            break;
        }
        sock->fd = socket(PF_INET, SOCK_DGRAM, 0);
        if(sock->fd >= 0)
        {          
            if(BindSocketToInetAddr(sock->fd, &myaddr) >= 0)
            {
                sock->state = DATAGRAM_UNICAST;
                sock->recvbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE);  
                sock->sendbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE);  
                sock->peerinfo.peertype = SLPD_PEER_REMOTE; 
                if(sock->recvbuf == 0 || sock->sendbuf == 0)
                {
                    SLPFatal("SLPD out of memory !!\n");
                }
                SLPDSocketListAdd(list,sock);
                SLPLog("UDP socket on %s ready\n",inet_ntoa(myaddr));
            }
            else
            {
                /* could not bind(), close the socket*/
                close(sock->fd);
                free(sock);
            }
        }

        /*------------------------------------------------*/
        /* Create TCP_LISTEN that will handle unicast TCP */
        /*------------------------------------------------*/
        sock = (SLPDSocket*)malloc(sizeof(SLPDSocket));
        if(sock == 0)
        {
            break;
        }
        sock->fd = socket(PF_INET, SOCK_STREAM, 0);
        if(sock->fd >= 0)
        {          
            if(BindSocketToInetAddr(sock->fd, &myaddr) >= 0)
            {
                if(listen(sock->fd,2) == 0)
                {
                    sock->state = SOCKET_LISTEN;
                    if(SLPDSocketListAdd(list,sock) == 0)
                    {
                        SLPFatal("Out of memory");
                    } 
                    
                    SLPLog("TCP socket on %s listening\n",inet_ntoa(myaddr));
                }
                else
                {
                    /* could not listen(), close the socket*/
                    close(sock->fd);
                    free(sock);
                }
            }
            else
            {
                /* could not bind, close the socket*/
                close(sock->fd);
                free(sock);   
            }
        }
        
        begin = end + 1;
    }     

    /*--------------------------------------------------------*/
    /* Create socket that will handle broadcast UDP           */
    /*--------------------------------------------------------*/
    
    sock = (SLPDSocket*)malloc(sizeof(SLPDSocket));
    if(sock == 0)
    {
        return;
    }
    sock->fd = socket(PF_INET, SOCK_DGRAM, 0);
    if(sock->fd >=0)
    {
        if(BindSocketToInetAddr(sock->fd, &bcastaddr) >= 0)
        {
            if(EnableBroadcast(sock->fd) == 0)
            {
                sock->state = DATAGRAM_BROADCAST;
                sock->recvbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE);  
                sock->sendbuf = SLPBufferAlloc(SLP_MAX_DATAGRAM_SIZE);
                sock->peerinfo.peeraddrlen = sizeof(sock->peerinfo.peeraddr);
                sock->peerinfo.peertype = SLPD_PEER_REMOTE; 
                if(sock->recvbuf == 0 || sock->sendbuf == 0)
                {
                    SLPFatal("SLPD out of memory !!\n");
                }
                SLPDSocketListAdd(list,sock);
                SLPLog("Broadcast socket for %s ready\n", inet_ntoa(bcastaddr));
            }
            else
            {
                /* could not add multicast membership */
                close(sock->fd);
                free(sock);
            }
        }
        else
        {
            /* could not bind(), close the socket*/
            close(sock->fd);
            free(sock);
        }
    }

}
Exemple #7
0
/*=========================================================================*/
void SLPDPropertyInit(const char* conffile)
/*=========================================================================*/
{
    struct in_addr  ifaddr;
    struct utsname  myname;
    struct hostent* myhostent;
    int             i;

    SLPPropertyReadFile(conffile);
   
    memset(&G_SlpdProperty,0,sizeof(G_SlpdProperty));
   
    /*-------------------------------------------------------------*/
    /* Set the properties with out hard defaults                   */
    /*-------------------------------------------------------------*/
    G_SlpdProperty.isBroadcastOnly = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.isBroadcastOnly"));
    G_SlpdProperty.passiveDADetection = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.passiveDADetection"));               
    G_SlpdProperty.activeDADetection = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.activeDADetection"));               
    G_SlpdProperty.activeDiscoveryAttempts = G_SlpdProperty.activeDADetection * 3;
    G_SlpdProperty.multicastTTL = atoi(SLPPropertyGet("net.slp.multicastTTL"));
    G_SlpdProperty.multicastMaximumWait = atoi(SLPPropertyGet("net.slp.multicastMaximumWait"));
    G_SlpdProperty.unicastMaximumWait = atoi(SLPPropertyGet("net.slp.unicastMaximumWait"));
    G_SlpdProperty.randomWaitBound = atoi(SLPPropertyGet("net.slp.randomWaitBound"));
    G_SlpdProperty.traceMsg = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceMsg"));
    G_SlpdProperty.traceReg = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceReg"));
    G_SlpdProperty.traceDrop = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceDrop"));
    G_SlpdProperty.traceDATraffic = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceDATraffic"));
    G_SlpdProperty.DAAddresses = SLPPropertyGet("net.slp.DAAddresses");
    G_SlpdProperty.DAAddressesLen = strlen(G_SlpdProperty.DAAddresses);
    G_SlpdProperty.useScopes = SLPPropertyGet("net.slp.useScopes");
    G_SlpdProperty.useScopesLen = strlen(G_SlpdProperty.useScopes);
    G_SlpdProperty.isDA = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.isDA"));
    G_SlpdProperty.locale = SLPPropertyGet("net.slp.locale");
    G_SlpdProperty.localeLen = strlen(G_SlpdProperty.locale);
    
 
    /*-------------------------------------*/
    /* Set the net.slp.interfaces property */
    /*-------------------------------------*/
    G_SlpdProperty.interfaces = SLPPropertyGet("net.slp.interfaces");
    if(*G_SlpdProperty.interfaces == 0)
    {
        /* put in all interfaces if none specified */
        if(uname(&myname) >= 0)
        {
            myhostent = gethostbyname(myname.nodename);
            if(myhostent != 0)
            {
                if(myhostent->h_addrtype == AF_INET)
                {
                    /* count the interfaces */
                    for(i=0; myhostent->h_addr_list[i];i++);
                                
                    /* allocate memory 16 bytes per interface*/
                    G_SlpdProperty.interfaces = (char*)malloc((i * 16) + 1);
                    if(G_SlpdProperty.interfaces == 0)
                    {
                        SLPFatal("slpd is out of memory!\n");
                    }
                    *(char*)G_SlpdProperty.interfaces = 0; /* null terminate */

                    for(i=0; myhostent->h_addr_list[i];i++)
                    {
                        memcpy(&ifaddr,myhostent->h_addr_list[i],sizeof(ifaddr));
                        if(i)
                        {
                            strcat((char*)G_SlpdProperty.interfaces,",");
                        }
                        strcat((char*)G_SlpdProperty.interfaces,inet_ntoa(ifaddr));
                    }
		        }
            }
        }
    }
    if(G_SlpdProperty.interfaces)
    {
        G_SlpdProperty.interfacesLen = strlen(G_SlpdProperty.interfaces);
    }
   
    /*---------------------------------------------------------*/
    /* Set the value used internally as the url for this agent */
    /*---------------------------------------------------------*/      
    G_SlpdProperty.myUrl = (const char*)malloc(25 + strlen(myname.nodename));
    if(G_SlpdProperty.myUrl == 0)
    {
       SLPFatal("slpd is out of memory!\n");
    }
    if(G_SlpdProperty.isDA)
    {
        strcpy((char*)G_SlpdProperty.myUrl,"service:directory-agent://");
    }
    else
    {
        strcpy((char*)G_SlpdProperty.myUrl,"service:service-agent://");
    }
    if(uname(&myname) >= 0)
    {
        /* 25 is the length of "service:directory-agent://" */
    	strcat((char*)G_SlpdProperty.myUrl,myname.nodename);
    }   
    G_SlpdProperty.myUrlLen = strlen(G_SlpdProperty.myUrl);
}
Exemple #8
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;
}
Exemple #9
0
/*=========================================================================*/
int main(int argc, char* argv[])
/*=========================================================================*/
{
    
    fd_set          readfds;
    fd_set          writefds;
    int             highfd      = 0;
    int             fdcount     = 0;
    SLPDSocket*     sock        = 0;
    SLPDSocket*     del         = 0;
    SLPDSocketList  socketlist  = {0,0};
    
    /*------------------------------*/
    /* Make sure we are root        */
    /*------------------------------*/
    if(getuid() != 0)
    {
        SLPFatal("slpd must be started by root\n");
    }
    
    /*------------------------*/
    /* Parse the command line */
    /*------------------------*/
    if(SLPDParseCommandLine(argc,argv))
    {
        SLPFatal("Invalid command line\n");
    }

    /*------------------------------*/
    /* Initialize the log file      */
    /*------------------------------*/
    SLPLogFileOpen(G_SlpdCommandLine.logfile, 0);

    SLPLog("****************************************\n");
    SLPLog("*** SLPD daemon started              ***\n");
    SLPLog("****************************************\n");
    SLPLog("command line = %s\n",argv[0]);
    
    /*--------------------------------------------------*/
    /* Initialize for the first time                    */
    /*--------------------------------------------------*/
    SLPDPropertyInit(G_SlpdCommandLine.cfgfile);
    SLPDDatabaseInit(G_SlpdCommandLine.regfile);
    SLPDSocketInit(&socketlist);
    
    /*---------------------------*/
    /* make slpd run as a daemon */
    /*---------------------------*/
    if(Daemonize(G_SlpdCommandLine.pidfile))
    {
        SLPFatal("Could not run as daemon\n");
    }
    
    /*-----------------------*/
    /* Setup signal handlers */ 
    /*-----------------------*/
    if(SetUpSignalHandlers())
    {
        SLPFatal("Could not set up signal handlers.\n");
    }

    /*------------------------------*/
    /* Set up alarm to age database */
    /*------------------------------*/
    alarm(SLPD_AGE_TIMEOUT);

    
    /*-----------*/
    /* Main loop */
    /*-----------*/
    while(G_SIGTERM == 0)
    {
        if(G_SIGHUP)
        {
            /* Reinitialize */
            SLPLog("****************************************\n");
            SLPLog("*** SLPD daemon restarted            ***\n");
            SLPLog("****************************************\n");
            SLPLog("Got SIGHUP reinitializing... \n");
            SLPDPropertyInit(G_SlpdCommandLine.cfgfile);
            SLPDDatabaseInit(G_SlpdCommandLine.regfile);
            SLPDSocketInit(&socketlist);                
            G_SIGHUP = 0;
        }

        /*--------------------------------------------------------*/
        /* Load the fdsets up with all of the sockets in the list */
        /*--------------------------------------------------------*/
        highfd = 0;
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);
        sock = socketlist.head;
        while(sock)
        {
            if(sock->fd > highfd)
            {
                highfd = sock->fd;
            }

            switch(sock->state)
            {
            case DATAGRAM_UNICAST:
            case DATAGRAM_MULTICAST:
                FD_SET(sock->fd,&readfds);
                break;
                
            case SOCKET_LISTEN:
                if(socketlist.count < SLPD_MAX_SOCKETS)
                {
                    FD_SET(sock->fd,&readfds);
                }
                break;
    
            case STREAM_READ:
            case STREAM_FIRST_READ:
                FD_SET(sock->fd,&readfds);
                break;
  
            case STREAM_WRITE:
            case STREAM_FIRST_WRITE:
                FD_SET(sock->fd,&writefds);
                break;

            case SOCKET_CLOSE:
            default:
                break;
            }
    
            sock = (SLPDSocket*)sock->listitem.next;
        }
        
        /*-----------------------------------------------*/
        /* Check to see if we we should age the database */
        /*-----------------------------------------------*/
        /* there is a reason this is here instead of somewhere else, but I */
        /* can't remember what it was.                                     */
        if(G_SIGALRM)
        {
            SLPDDatabaseAge(SLPD_AGE_TIMEOUT);
            G_SIGALRM = 0;
            alarm(SLPD_AGE_TIMEOUT);
        }
        
        /*-------------*/
        /* Main select */
        /*-------------*/
        fdcount = select(highfd+1,&readfds,&writefds,0,0);
        if(fdcount > 0)
        {
            sock = socketlist.head;
            while(sock && fdcount)
            {
                if(FD_ISSET(sock->fd,&readfds))
                {
                    switch(sock->state)
                    {
                    
                    case SOCKET_LISTEN:
                        HandleSocketListen(&socketlist,sock);
                        break;

                    case DATAGRAM_UNICAST:
                    case DATAGRAM_MULTICAST:
                        HandleDatagramRead(&socketlist,sock);
                        break;                      
                
                    case STREAM_READ:
                    case STREAM_FIRST_READ:
                        HandleStreamRead(&socketlist,sock);
                        break;

                    default:
                        break;
                    }

                    fdcount --;
                } 

                if(FD_ISSET(sock->fd,&writefds))
                {
                    HandleStreamWrite(&socketlist,sock);
                    fdcount --;
                }   

                /* Should we close the socket */

                /* TODO: Close aged sockets */
                if(sock->state == SOCKET_CLOSE)
                {
                    del = sock;
                    sock = (SLPDSocket*)sock->listitem.next;
                    HandleSocketClose(&socketlist,del);
                }
                else
                {
                    sock = (SLPDSocket*)sock->listitem.next;
                }
            }
        }
    }

    SLPLog("Got SIGTERM.  Going down\n");

    return 0;
}