Пример #1
0
/* print - print a message */
void print(int msg)
{
    int ch;

    msg_open(msg);
    while (ch = msg_byte())
	trm_chr(ch);
}
Пример #2
0
/*
 * PUBLIC: int f_msgcat __P((SCR *, OPTION *, char *, u_long *));
 */
int
f_msgcat(
	SCR *sp,
	OPTION *op,
	char *str,
	u_long *valp)
{
	(void)msg_open(sp, str);
	return (0);
}
Пример #3
0
extern void
daemon_init(msg_dest_t log_dest, const char *program, int facility, const char *pidfile, const char *username, const char *groupname)
{
	pid_t pid;
	int i;
	FILE *pid_fp;
	int sigs[] = { SIGHUP, SIGINT, SIGQUIT, SIGTSTP, SIGTTIN, SIGTTOU };
	struct passwd *pw;
	struct group *grp;

	/* make sure all those nice signals are going to be ignored */
	for (i = 0; i < sizeof(sigs) / sizeof(int); i++)
	{
		if (!_daemon_handle_signal(sigs[i], SIG_IGN))
		{
			msg_log(LOG_ERR, "Fatal error in daemon_init(): %s\n", strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	/* stalking off to background... */
	switch (pid = fork())
	{
		case -1:
			msg_log(LOG_ERR, "Fatal error in fork(): %s\n", strerror(errno));
			exit(EXIT_FAILURE);
			break;
		case 0:
			msg_close();
			msg_open(log_dest, program, LOG_PID, facility);
			break;
		default:
			exit(EXIT_SUCCESS);
			break;
	}

	/* get rid of the associated terminal */
	if (setsid() < 0)
	{
		msg_log(LOG_ERR, "Fatal error in setsid(): %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}

	/* make sure we cannot be prosecuted by a not yet controlling terminal */
	switch (pid = fork())
	{
		case -1:
			msg_log(LOG_ERR, "Fatal error in fork(): %s\n", strerror(errno));
			exit(EXIT_FAILURE);
			break;
		case 0:
			break;
		default:
			exit(EXIT_SUCCESS);
			break;
	}

	/* close unnecessary file descriptors */
	close(STDIN_FILENO);
	close(STDOUT_FILENO);
	close(STDERR_FILENO);

	/* change working directory */
	chdir("/");

	/* set default file mode creation mask */
	umask(0);

	/* write PID to pidfile */
	if (NULL != pidfile)
	{
		pid_fp = fopen(pidfile, "w");
		if (NULL == pid_fp)
		{
			msg_log(LOG_ERR, "Fatal error in fopen(): %s\n", strerror(errno));
			exit(EXIT_FAILURE);
		}
		fprintf(pid_fp, "%d", (int)getpid());
		fclose(pid_fp);
	}

	/* change user and group id */
	if (NULL != groupname)
	{   
		grp = getgrnam(groupname);      /* using a non-threadsafe function is ok here */
		if (0 != setgid(grp->gr_gid))
			msg_log(LOG_WARNING, "Unable to change GID to %d (%s): %s\n", (int)grp->gr_gid, groupname, strerror(errno));
		else
			msg_log(LOG_INFO, "Changed GID to %d (%s)\n", (int)grp->gr_gid, groupname);
	}

	if (NULL != username)
	{
		pw = getpwnam(username);		/* using a non-threadsafe function is ok here */
		if  (0 != setuid(pw->pw_uid))
			msg_log(LOG_WARNING, "Unable to change UID to %d (%s): %s\n", (int)pw->pw_uid, username, strerror(errno));
		else
			msg_log(LOG_INFO, "Changed UID to %d (%s)\n", (int)pw->pw_uid, username);
	}
}
Пример #4
0
void exread( int sockfd ) {
    void* ptr;
    conn_data_t* conn_data = connections[ sockfd ];

    if ( !conn_data->buffer ) {
        conn_data->buffer = malloc(PACK_DATA_SIZE);
        conn_data->bufferlen = 0;
        memset( conn_data->buffer, 0, PACK_DATA_SIZE );
    }

    website_t* website;

    ssize_t len = zs_read( sockfd, conn_data->buffer + conn_data->bufferlen, PACK_DATA_SIZE - conn_data->bufferlen );

    // TODO: wait for entire header before looking up website
    if ( len <= 0 ) {
cleanup:
        // cleanup
        cleanup_connection( sockfd );
        return;
    }

    if ( conn_data->postlen == -1 ) /* if we have received all the data already, ignore */
        return;

    conn_data->bufferlen += len;
    //printf( "%d: read %zu\n", sockfd, len );

    ptr = conn_data->buffer;

    if ( conn_data->website_sockfd == -1 ) {
        /* If req_info is NULL this is the start of a request and the
           HTTP request headers need to be parsed. */
        struct hostent* hp;
        hp = NULL;//gethostbyaddr( (char*) &conn_data->addr, sizeof( conn_data->addr ), AF_INET );

        char* endofhdrs;
        if ( !( endofhdrs = strnstr( conn_data->buffer, HTTP_HDR_ENDL HTTP_HDR_ENDL, PACK_DATA_SIZE ) ) ) {
            if ( conn_data->bufferlen == PACK_DATA_SIZE ) {
                /* If the end of the headers was not found the request was either
                   malformatted or too long, DO NOT send to website. */
                zs_write( sockfd, html_error_414, sizeof( html_error_414 ) );
                syslog( LOG_WARNING, "exread: headers to long" );
                goto cleanup;
            }
            // Have not received the full header yet, wait
            zs_set_read( sockfd );
            return;
        }
        endofhdrs += sizeof( HTTP_HDR_ENDL HTTP_HDR_ENDL ) - 1;
        /* Get HTTP request type */
        if ( startswith( conn_data->buffer, HTTP_GET ) )
            conn_data->request_type = HTTP_GET_TYPE;
        else if ( startswith( conn_data->buffer, HTTP_POST ) )
            conn_data->request_type = HTTP_POST_TYPE;
        else {
            zs_write( sockfd, html_error_400, sizeof( html_error_400 ) );
            goto cleanup;
        }

        /* Find website for request from HTTP header */
        char urlbuf[ PACK_DATA_SIZE ];
        if ( !get_url_from_http_header( conn_data->buffer, urlbuf, sizeof( urlbuf ) ) ) {
            //syslog( LOG_WARNING, "exread: no url found in http request headers: %s %s",
            //  inet_ntoa( conn_data->addr.sin_addr ), hp ? hp->h_name : "" );
            zs_write( sockfd, html_error_400, sizeof( html_error_400 ) );
            goto cleanup;
        }

        if ( !( website = website_find( urlbuf, conn_data->is_https ? "https://" : "http://",
                                        inet_ntoa( zs_get_addr( conn_data->exlisnfd )->sin_addr ) ) ) ) {
            //syslog( LOG_WARNING, "exread: no website to service request: %s %s %s",
            //  inet_ntoa( conn_data->addr.sin_addr ), hp ? hp->h_name : "", urlbuf );
            zs_write( sockfd, html_error_404, sizeof( html_error_404 ) );
            goto cleanup;
        }

        /* Set the website id so that furthur sections of this
           request can check if the website is still alive. */
        conn_data->website_sockfd = website->sockfd;

        /* Check the websites socket to make sure the request came in on
           the right socket. */
        website_data_t* website_data = website->udata;

        if ( website_data->exlisnfd != conn_data->exlisnfd ) {
            //syslog( LOG_WARNING, "exread: no website to service request: %s %s %s",
            //  inet_ntoa( conn_data->addr.sin_addr ), hp ? hp->h_name : "", urlbuf );
            zs_write( sockfd, html_error_404, sizeof( html_error_404 ) );
            goto cleanup;
        }
        //printf( "%s\n", buffer );

        /* Create a new message to send the request to the corresponding
           website. The msgid should be set to the external file descriptor
           to send the response back to. */
        conn_data->msgid = msg_open( website->sockfd, sockfd );
        zs_set_write( sockfd );

        // If request_type is POST check if there is content after the HTTP header
        char postlenbuf[ 32 ];
        memset( postlenbuf, 0, sizeof( postlenbuf ) );
        if ( conn_data->request_type == HTTP_POST_TYPE && ( ptr = strnstr( conn_data->buffer, "Content-Length: ", PACK_DATA_SIZE ) ) ) {
            char* tmp = strnstr( ptr + 16, HTTP_HDR_ENDL, PACK_DATA_SIZE - ( (long)ptr + 16 - (long)conn_data->buffer ) );
            if ( !tmp ) {
                zs_write( sockfd, html_error_400, sizeof( html_error_400 ) );
                goto cleanup;
            }
            memcpy( postlenbuf, ptr + 16, (long) tmp - (long) ( ptr + 16 ) );
            conn_data->postlen = strtoumax( postlenbuf, NULL, 0 );
            if ( conn_data->postlen < 0 ) {
                zs_write( sockfd, html_error_400, sizeof( html_error_400 ) );
                goto cleanup;
            }
        }

        // Write the message length
        size_t msglen = ( endofhdrs - conn_data->buffer ) + conn_data->postlen + sizeof( conn_data->addr.sin_addr ) + 1;
        if ( hp ) msglen += strlen( hp->h_name );
        if ( msg_write( website->sockfd, conn_data->msgid, (void*) &msglen, sizeof( size_t ) ) == -1 ) {
            zs_write( sockfd, html_error_502, sizeof( html_error_502 ) );
            goto cleanup;
        }

        // Write the ip address and hostname of the request
        if ( msg_write( website->sockfd, conn_data->msgid, (void*) &conn_data->addr.sin_addr, sizeof( conn_data->addr.sin_addr ) ) == -1
                || ( hp && msg_write( website->sockfd, conn_data->msgid, (void*) hp->h_name, strlen( hp->h_name ) ) == -1 )
                || msg_write( website->sockfd, conn_data->msgid, (void*) "\0", 1 ) == -1 ) {
            zs_write( sockfd, html_error_502, sizeof( html_error_502 ) );
            goto cleanup;
        }

        // Send the whole header to the website
        if ( msg_write( website->sockfd, conn_data->msgid, (void*) conn_data->buffer, ( endofhdrs - conn_data->buffer ) ) == -1 ) {
            zs_write( sockfd, html_error_502, sizeof( html_error_502 ) );
            goto cleanup;
        }

        ptr = endofhdrs;
    }

    else {
        if ( !( website = website_get_by_sockfd( conn_data->website_sockfd ) ) ) {
            //	syslog( LOG_WARNING, "exread: no website to service request" );
            zs_write( sockfd, html_error_502, sizeof( html_error_502 ) );
            goto cleanup;
        }
    }

    if ( conn_data->request_type == HTTP_POST_TYPE && conn_data->postlen ) {
        int left = conn_data->bufferlen - ( ptr - (void*)conn_data->buffer );

        if ( left > conn_data->postlen )
            conn_data->postlen = left;

        if ( msg_write( website->sockfd, conn_data->msgid, (void*) ptr, left ) == -1 ) {
            zs_write( sockfd, html_error_502, sizeof( html_error_502 ) );
            goto cleanup;
        }

        conn_data->postlen -= left;
    }

    if ( !conn_data->postlen ) { /* If there isn't more data coming, */
        msg_flush( website->sockfd, conn_data->msgid );

        /* must make sure to keep sockfd in read mode to detect a connection close from
           the other end */
        conn_data->postlen = -1;
        zs_set_read( sockfd );
    } else
        msg_set_write( website->sockfd, conn_data->msgid );

    free( conn_data->buffer );
    conn_data->buffer = NULL;
    //printf( "%d: still needs %d post data\n", sockfd, conn_data->postlen );
}