int WebSocketHandshake::readServerHandshake(const char* header, size_t len)
{
    m_mode = Incomplete;
    int statusCode;
    String statusText;
    int lineLength = readStatusLine(header, len, statusCode, statusText);
    if (lineLength == -1)
        return -1;
    if (statusCode == -1) {
        m_mode = Failed; // m_failureReason is set inside readStatusLine().
        return len;
    }
    LOG(Network, "WebSocketHandshake %p readServerHandshake() Status code is %d", this, statusCode);

    m_serverHandshakeResponse = ResourceResponse();
    m_serverHandshakeResponse.setHTTPStatusCode(statusCode);
    m_serverHandshakeResponse.setHTTPStatusText(statusText);

    if (statusCode != 101) {
        m_mode = Failed;
        m_failureReason = "Unexpected response code: " + String::number(statusCode);
        return len;
    }
    m_mode = Normal;
    if (!strnstr(header, "\r\n\r\n", len)) {
        // Just hasn't been received fully yet.
        m_mode = Incomplete;
        return -1;
    }
    const char* p = readHTTPHeaders(header + lineLength, header + len);
    if (!p) {
        LOG(Network, "WebSocketHandshake %p readServerHandshake() readHTTPHeaders() failed", this);
        m_mode = Failed; // m_failureReason is set inside readHTTPHeaders().
        return len;
    }
    if (!checkResponseHeaders()) {
        LOG(Network, "WebSocketHandshake %p readServerHandshake() checkResponseHeaders() failed", this);
        m_mode = Failed;
        return p - header;
    }

    m_mode = Connected;
    return p - header;
}
Example #2
0
int get_mime_len(uchar **data) { // Возвращает строку миме-параметра
    uchar *str = *data;
    int sl,len;
    sl = strlen(str);
    len=0; // Будем коллектить длину -)))
    while(sl>0) {
        int ipos = strnstr(str,sl,"\r\n",-1);
        if (ipos<0) {
            len+= sl;    // Больше строк нет - возвращаем все...
            break;
        }
        ipos+=2;
        str+=ipos;
        sl-=ipos;
        len+=ipos;
        if (sl==0 || *str>32) break; // Следующая строка - начало нового параметра...
    }
    return len;
}
Example #3
0
static bool is_fota_boot(void)
{
	char *ptr, buf[11];
	unsigned long val;

	ptr = strnstr(saved_command_line, WARMBOOT_STR, COMMAND_LINE_SIZE);
	if (!ptr)
		return 0;

	ptr += sizeof(WARMBOOT_STR) - 1;
	strlcpy(buf, ptr, sizeof(buf));

	if (!kstrtoul(buf, 16, &val)) {
		if (val == FOTA_BOOT_REASON)
			return 1;
	}

	return 0;
}
Example #4
0
int print_unique(char *loaded){
    char * ptr, *unique, *addr;
    
    addr = unique = (char *)malloc(sizeof(loaded));
    if(unique == NULL)
        return EXIT_FAILURE;
    strcpy(unique, "");
    
    ptr = strtok(loaded, "\n");
    do{
        if(strnstr(unique, ptr, strlen(ptr)) == NULL){
            strcat(unique, ptr);
            strcat(unique, "\n");
        }
        ptr = strtok(NULL, "\n");
    }while(ptr != NULL);
    
    printf("Unique strings:\n%s", unique);
    free(addr);
    return EXIT_SUCCESS;
}
Example #5
0
int interactive(usb_dev_handle* device) {
	int len;
	char* commandBuffer = NULL;

	do {
		do {
			usleep(100000);
			len = get_response(device);

			if(len > 0) {
				fwrite(response_buffer, 1, len, stdout);
				fflush(stdout);
			}
		} while(len > 0 && strnstr(response_buffer, "] ", len) == NULL);

		if(len < 0)
			break;

ProcessCommand:
		if(commandBuffer != NULL)
			free(commandBuffer);

		commandBuffer = readline(NULL);
		if(commandBuffer && *commandBuffer) {
			add_history(commandBuffer);
		}

		if(strncmp(commandBuffer, "sendfile ", sizeof("sendfile ") - 1) == 0) {
			char* file = commandBuffer + sizeof("sendfile ") - 1;
			send_file(device, file);
			goto ProcessCommand;
		} else {
			send_command(device, commandBuffer);
			send_command(device, "\n");
		}

	} while(1);

	return 0;
}
Example #6
0
static void proxy_client_process(int fd)
{
    char buf[1024];
    size_t buflen = 0;
    ssize_t val;

    /* Read request (and possibly more) */
    while (strnstr(buf, "\r\n\r\n", buflen) == NULL)
    {
        val = recv(fd, buf + buflen, sizeof (buf) - buflen - 1, 0);
        if (val <= 0)
            assert(!"Incomplete request");
        buflen += val;
    }

    buf[buflen] = '\0';

    char host[64];
    unsigned port, ver;
    int offset;

    assert(sscanf(buf, "CONNECT %63[^:]:%u HTTP/1.%1u%n", host, &port, &ver,
                  &offset) == 3);
    assert(!strcmp(host, "www.example.com"));
    assert(port == 443);
    assert(ver == 1);

    assert(sscanf(buf + offset + 2, "Host: %63[^:]:%u", host, &port) == 2);
    assert(!strcmp(host, "www.example.com"));
    assert(port == 443);

    assert(strstr(buf, "\r\nProxy-Authorization: Basic "
                  "QWxhZGRpbjpvcGVuIHNlc2FtZQ==\r\n") != NULL);

    const char resp[] = "HTTP/1.1 500 Failure\r\n\r\n";

    val = write(fd, resp, strlen(resp));
    assert((size_t)val == strlen(resp));
    shutdown(fd, SHUT_WR);
}
Example #7
0
void
end_outcache()
{
	char *ptr;
	int len;
	fclose(stdout);
	*stdout = oldout;
	if (!myoutbuf)
		return;
	ptr = strstr(myoutbuf, "\n\n");
	if (!ptr) {
		printf("\n\nfaint! 出毛病了...");
		return;
	}
	if (strnstr(myoutbuf, "Content-type: ", ptr - myoutbuf)) {
		len = myoutsize - (ptr - myoutbuf) - 2;
		printf("Content-Length: %d\n", len);
	}
	fputs(myoutbuf, stdout);
	free(myoutbuf);
	myoutbuf = NULL;
}
Example #8
0
void
parse_ns_str(const char *ns_str, char *ctrlr_str, int *nsid)
{
	char	*nsloc;

	/*
	 * Pull the namespace id from the string. +2 skips past the "ns" part
	 *  of the string.  Don't search past 10 characters into the string,
	 *  otherwise we know it is malformed.
	 */
	nsloc = strnstr(ns_str, NVME_NS_PREFIX, 10);
	if (nsloc != NULL)
		*nsid = strtol(nsloc + 2, NULL, 10);
	if (nsloc == NULL || (*nsid == 0 && errno != 0))
		errx(1, "invalid namespace ID '%s'", ns_str);

	/*
	 * The controller string will include only the nvmX part of the
	 *  nvmeXnsY string.
	 */
	snprintf(ctrlr_str, nsloc - ns_str + 1, "%s", ns_str);
}
Example #9
0
MachinePower GetMachinePower()
{
	char nameBuf[64];
	size_t nameLen = sizeof(nameBuf);
	memset(nameBuf, 0, sizeof(nameBuf));
	sysctlbyname("hw.model", &nameBuf, &nameLen, NULL, NULL);
	if (nameLen == 0)
		return MACHINE_POWER_CAPABLE; // assume capable
	else
	{
		// check our list
		SDL_RWops* ops = ResourceManager::OpenFile("Config/MacModels.txt");
		if (!ops)
			return MACHINE_POWER_CAPABLE;
		size_t length;
		void* ptr = ResourceManager::ReadFull(&length, ops, 1);
		if (!ptr)
			return MACHINE_POWER_CAPABLE;
		bool found = strnstr((const char*)ptr, nameBuf, length);
		free(ptr);
		return found ? MACHINE_POWER_MIGHTY : MACHINE_POWER_WIMPY;
	}
}
Example #10
0
int main(int argc, char *argv[])
{
  if (argc < 2)
    {
      puts("Usage: ./mygrep <pattern> <name>");
    }
  else
    {
      FILE *f = fopen(argv[2], "r");
      int str_len;
      size_t buf_siz;
      char *string; 
      char *pattern = argv[1];
      
      while ((str_len = getline(&string, &buf_siz, f)) > 0)
	{
	  if (strnstr(string, pattern, str_len))
	    printf("%s", string);
	}

      fclose(f);
    }
  return 0; 
}
Example #11
0
void
logpage(int argc, char *argv[])
{
	int				fd, nsid, len;
	int				log_page = 0, pageflag = false;
	int				hexflag = false;
	int				allow_ns = false;
	char				ch, *p, *nsloc = NULL;
	char				*cname = NULL;
	size_t				size;
	void				*buf;
	struct logpage_function		*f;
	struct nvme_controller_data	cdata;
	print_fn_t			print_fn;

	while ((ch = getopt(argc, argv, "p:x")) != -1) {
		switch (ch) {
		case 'p':
			/* TODO: Add human-readable ASCII page IDs */
			log_page = strtol(optarg, &p, 0);
			if (p != NULL && *p != '\0') {
				fprintf(stderr,
				    "\"%s\" not valid log page id.\n",
				    optarg);
				logpage_usage();
			/* TODO: Define valid log page id ranges in nvme.h? */
			} else if (log_page == 0 ||
				   (log_page >= 0x04 && log_page <= 0x7F) ||
				   (log_page >= 0x80 && log_page <= 0xBF)) {
				fprintf(stderr,
				    "\"%s\" not valid log page id.\n",
				    optarg);
				logpage_usage();
			}
			pageflag = true;
			break;
		case 'x':
			hexflag = true;
			break;
		}
	}

	if (!pageflag) {
		printf("Missing page_id (-p).\n");
		logpage_usage();
	}

	/* Check that a controller and/or namespace was specified. */
	if (optind >= argc)
		logpage_usage();

	/*
	 * The log page attribtues indicate whether or not the controller
	 * supports the SMART/Health information log page on a per
	 * namespace basis.
	 */
	cname = malloc(strlen(NVME_CTRLR_PREFIX) + 2);
	len = strlen(NVME_CTRLR_PREFIX) + 1;
	cname = strncpy(cname, argv[optind], len);
	open_dev(cname, &fd, 1, 1);
	read_controller_data(fd, &cdata);

	if (log_page == NVME_LOG_HEALTH_INFORMATION && cdata.lpa.ns_smart != 0)
		allow_ns = true;

	/* If a namespace id was specified, validate it's use */
	if (strstr(argv[optind], NVME_NS_PREFIX) != NULL) {
		if (!allow_ns) {
			if (log_page != NVME_LOG_HEALTH_INFORMATION) {
				fprintf(stderr,
				    "Namespace ID not valid for log page %d.\n",
				    log_page);
			} else if (cdata.lpa.ns_smart == 0) {
				fprintf(stderr,
				    "Controller does not support per "
				    "namespace SMART/Health information.\n");
			}
			close(fd);
			exit(EX_IOERR);
		}
		nsloc = strnstr(argv[optind], NVME_NS_PREFIX, 10);
		if (nsloc != NULL)
			nsid = strtol(nsloc + 2, NULL, 10);
		if (nsloc == NULL || (nsid == 0 && errno != 0)) {
			fprintf(stderr,
			    "Invalid namespace ID %s.\n",
			    argv[optind]);
			close(fd);
			exit(EX_IOERR);
		}

		/*
		 * User is asking for per namespace log page information
		 * so close the controller and open up the namespace.
		 */
		close(fd);
		open_dev(argv[optind], &fd, 1, 1);
	} else
		nsid = NVME_GLOBAL_NAMESPACE_TAG;

	print_fn = print_hex;
	if (!hexflag) {
		/*
		 * See if there is a pretty print function for the
		 *  specified log page.  If one isn't found, we
		 *  just revert to the default (print_hex).
		 */
		f = logfuncs;
		while (f->log_page > 0) {
			if (log_page == f->log_page) {
				print_fn = f->fn;
				break;
			}
			f++;
		}
	}

	/* Read the log page */
	switch (log_page) {
	case NVME_LOG_ERROR:
		size = sizeof(struct nvme_error_information_entry);
		size *= (cdata.elpe + 1);
		break;
	case NVME_LOG_HEALTH_INFORMATION:
		size = sizeof(struct nvme_health_information_page);
		break;
	case NVME_LOG_FIRMWARE_SLOT:
		size = sizeof(struct nvme_firmware_page);
		break;
	default:
		size = DEFAULT_SIZE;
		break;
	}

	buf = get_log_buffer(size);
	read_logpage(fd, log_page, nsid, buf, size);
	print_fn(buf, size);

	close(fd);
	exit(EX_OK);
}
Example #12
0
void* doNetWork(struct threadData* td) {
    /*Response Variables*/
    struct http_request request;
    int bytesSent;
    int sendResponse;
    int controller;
    int status;
    char * response;
    /* Request variables */
    int readAmount;
    int totalRead;
    int flags; 
    int j,k;
    int contentLength;
    int contentLengthRecieved;
    int contentLengthPosition;
    char * tempBuff;
    char * raw_message;
    char contentLengthBuff[100];
    bytesSent = 0;
    sendResponse =0;

    response = malloc(sizeof(char)*STARTING_RESPONSE_SIZE);
    if(response == NULL){
        NETWORK_LOG_LEVEL_1("Fatal: Failed to allocate memory for response");
        response = "{}";
        status = 500;
        goto internal_err;
    }
    memset(response,0,sizeof(char)*STARTING_RESPONSE_SIZE);

    raw_message = malloc(1+sizeof(char)*BUFSIZ); /* Just enough space for the first read, to determine content length */
    if(raw_message == NULL){
        /* Internal Problem! */
        NETWORK_LOG_LEVEL_1("Fatal: Failed to allocate memory for first-read temporary buffer");
        response[0]='{'; response[1]='}'; response[2]='\0';
        status = 500;
        goto internal_err;
    }
    memset(raw_message, 0,1+sizeof(char)*BUFSIZ);
    tempBuff = NULL; /* temp buff will be used to realloc */
        

    /* Accept and read incoming request  */
    if(td->clientfd == -1)
        goto bad_client_id;

    readAmount=totalRead=contentLengthRecieved =contentLengthPosition= contentLength = 0;

    NETWORK_LOG_LEVEL_2_NUM("Accepted Client Request on File Descriptor ", td->clientfd);
    readAmount = 1; /* Sentinal */
    flags = fcntl(td->clientfd, F_GETFL, 0);
    fcntl(td->clientfd, F_SETFL, flags | O_NONBLOCK);
    contentLength = -1; /* Sentinal */
    while(readAmount != 0){
        readAmount = read(td->clientfd,raw_message+totalRead,BUFSIZ);    
        if(readAmount == -1){
            if(errno == EAGAIN && totalRead == 0)
                continue;
            else if(contentLengthRecieved != contentLength)
                continue;
            else
                readAmount = 0;
        }else{
            NETWORK_LOG_LEVEL_2_NUM("Reading Data From Socket", td->clientfd);
            /* Since we're here that means we have at least 
             * the beginning of the request itself but we're
             * waiting for more. So determine the content-length
             * and then figure out if we have all of it or not
            */
            contentLengthPosition = strnstr("Content-Length", raw_message, BUFSIZ);                    
            if(contentLengthPosition == -1){
                /* You didn't send us a content length, carry on! 
                 * so no data, so just url, so good bye.
                */
                contentLengthRecieved = contentLength = readAmount = 0;
            }else{
                if(totalRead == 0){                            
                    /* Convert the content length 
                    * reuse this connections buffer.
                    */
                    bzero(contentLengthBuff, sizeof contentLengthBuff); /* Only what we need */
                    contentLength = contentLengthPosition;
                    contentLength+=strlen("Content-Length: "); /* Skip the text */
                     
                    for(k=0; k < (int)sizeof(contentLengthBuff) && *(raw_message + contentLength) != '\0' && *(raw_message + contentLength) != '\r'; ++k, contentLength++)
                        contentLengthBuff[k] = *(raw_message + contentLength);
                    contentLengthBuff[k] = '\0';
                    contentLength = atoi(contentLengthBuff);                            
                    
                    /* Malloc for the content Length 
                     * j is the position of the data, all things prior 
                     * need to be conserved as well
                    */
                    if( contentLength > 0 ){
                        tempBuff = malloc(5+ strlen(raw_message) + contentLength + BUFSIZ);
                        if(tempBuff == NULL){
                            free(raw_message);
                            NETWORK_LOG_LEVEL_1("Could not reallocate memory during request data acquisition");
                            goto internal_err;
                        }else{
                            memset(tempBuff, 0, 5+ strlen(raw_message) + contentLength + BUFSIZ);
                            strcpy(tempBuff, raw_message);
                            swapCharPtr(&tempBuff, &raw_message);
                            free(tempBuff);
                        }
                    }
                }

                /* We've said a content length now, and we need 
                * determine how much we've actually recieved
                * no need to store it, just count it with j. 
                */
                j = strnstr("\r\n\r\n", raw_message, BUFSIZ);
                if(j != -1){
                    j+=4; /* skip newlines */
                    j+= contentLengthRecieved;
                    for(contentLengthRecieved = (contentLengthRecieved==0 ? 0 : contentLengthRecieved); (unsigned int)j < strlen(raw_message); ++j, ++contentLengthRecieved)
                        ;                            
                }else{   
                    /* Could not find content...*/
                    if(contentLength <= 0)
                        readAmount = 0; /* Get out */
                    else
                        contentLengthRecieved = 0; /* Haven't received it yet */
                }
            }
            /* Important to do this last as the totalRead is what
             * determines if we malloc for content or not
            */
            
            fprintf(stderr, "Recieving Data From Socket %d: %d/%d\n", td->clientfd ,contentLengthRecieved, contentLength);    
            
            totalRead += readAmount;                
            if(contentLength == contentLengthRecieved) 
                readAmount = 0;      
        }
    }
    if(totalRead > THREAD_DATA_MAX_SIZE)
        NETWORK_LOG_LEVEL_1("Warning: Total Read Greater than Buffer Length");

    /*Blank JSON response for no control*/
    *(response+1)='{'; *(response+1)='}'; *(response+2)='\0';
    status = 200;
    parseRequest(&request, raw_message);

    /* Pass the request off to a handler */
    controller = determineController(request.url);
    /* Determine method and call. */
    switch(controller){
        case HEARTBEAT_CONTROLLER :
            NETWORK_LOG_LEVEL_2("Heartbeat Controller Processing Request.");
            status = heartbeat_controller(response, STARTING_RESPONSE_SIZE);
            break;
        case COMMENTS_CONTROLLER :
            NETWORK_LOG_LEVEL_2("Comments Controller Processing Request.");
            status = comment_controller(&request, &response,  STARTING_RESPONSE_SIZE);
            break;
        case HEATMAP_CONTROLLER :
            NETWORK_LOG_LEVEL_2("Heatmap Controller Processing Request.");
            status = heatmap_controller(&request, &response,  STARTING_RESPONSE_SIZE);
            break;
        case MARKER_CONTROLLER :
            NETWORK_LOG_LEVEL_2("Marker Controller Processing Request.");
            status = marker_controller(&request, &response,  STARTING_RESPONSE_SIZE);
            break;
        case REPORT_CONTROLLER :
            NETWORK_LOG_LEVEL_2("Report Controller Processing Request.");
            status = report_controller(&request, &response,  STARTING_RESPONSE_SIZE);
            break;
        default:
            NETWORK_LOG_LEVEL_2("Unknown URL. Refusing to process request.");
            /* We have no clue what the client is talking about with their url */
            status = 404;
            break;
    }
    

    /* Log and clean up. */
    NETWORK_LOG_LEVEL_1("Incoming Request:")
    NETWORK_LOG_LEVEL_1(request.url);
    if(request.contentLength > 0){
        NETWORK_LOG_LEVEL_2("Incoming Data:");
        NETWORK_LOG_LEVEL_2_NUM("Content length of Data: ", request.contentLength);
        NETWORK_LOG_LEVEL_2(request.data);
    }
    if(request.contentLength > 0)
        free(request.data);

    internal_err:
    td->msg = malloc(strlen(response) + 256);
    if(td->msg == NULL){
        NETWORK_LOG_LEVEL_2_NUM("Fatal: Not enough memory for HTTP response", (int)strlen(response)+256);
        free(raw_message);
        free(response);
        close(td->clientfd);
        return NULL;
    }
    memset(td->msg,0,strlen(response)+256);
    createResponse(response,td->msg,status);
    td->msg[strlen(td->msg)] = '\0';\



    bad_client_id: 
    if(td->clientfd != -1){
        do{
            sendResponse = send(td->clientfd,(td->msg)+bytesSent,strlen(td->msg)-bytesSent,0);  
            if(sendResponse == -1){
                NETWORK_LOG_LEVEL_2(strerror(errno));    
            }else{
                bytesSent += sendResponse;
            }
            NETWORK_LOG_LEVEL_1("Sending Response:");
            NETWORK_LOG_LEVEL_1( ( td->msg )+bytesSent  ); 
            NETWORK_LOG_LEVEL_2_NUM("Bytes sent to client: ", bytesSent);
            
        } while(bytesSent < (int)strlen(td->msg) -1 );
        close(td->clientfd);
    }else{
        NETWORK_LOG_LEVEL_2("File Descriptor invalid. If shutting down there is no problem.");
        NETWORK_LOG_LEVEL_2("If not shutting down, there was an issue sending data to the client.");
    }
    free(td->msg);
    free(raw_message);
    free(response);
    return NULL;
}
Example #13
0
void LogKlog::sniffTime(log_time &now,
                        const char **buf, size_t len,
                        bool reverse) {
    const char *cp = now.strptime(*buf, "[ %s.%q]");
    if (cp && (cp >= &(*buf)[len])) {
        cp = NULL;
    }
    if (cp) {
        static const char healthd[] = "healthd";
        static const char battery[] = ": battery ";

        len -= cp - *buf;
        if (len && isspace(*cp)) {
            ++cp;
            --len;
        }
        *buf = cp;

        if (isMonotonic()) {
            return;
        }

        const char *b;
        if (((b = strnstr(cp, len, suspendStr)))
                && ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) {
            len -= b - cp;
            calculateCorrection(now, b, len);
        } else if (((b = strnstr(cp, len, resumeStr)))
                && ((size_t)((b += sizeof(resumeStr) - 1) - cp) < len)) {
            len -= b - cp;
            calculateCorrection(now, b, len);
        } else if (((b = strnstr(cp, len, healthd)))
                && ((size_t)((b += sizeof(healthd) - 1) - cp) < len)
                && ((b = strnstr(b, len -= b - cp, battery)))
                && ((size_t)((b += sizeof(battery) - 1) - cp) < len)) {
            // NB: healthd is roughly 150us late, so we use it instead to
            //     trigger a check for ntp-induced or hardware clock drift.
            log_time real(CLOCK_REALTIME);
            log_time mono(CLOCK_MONOTONIC);
            correction = (real < mono) ? log_time::EPOCH : (real - mono);
        } else if (((b = strnstr(cp, len, suspendedStr)))
                && ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) {
            len -= b - cp;
            log_time real;
            char *endp;
            real.tv_sec = strtol(b, &endp, 10);
            if ((*endp == '.') && ((size_t)(endp - b) < len)) {
                unsigned long multiplier = NS_PER_SEC;
                real.tv_nsec = 0;
                len -= endp - b;
                while (--len && isdigit(*++endp) && (multiplier /= 10)) {
                    real.tv_nsec += (*endp - '0') * multiplier;
                }
                if (reverse) {
                    if (real > correction) {
                        correction = log_time::EPOCH;
                    } else {
                        correction -= real;
                    }
                } else {
                    correction += real;
                }
            }
        }

        convertMonotonicToReal(now);
    } else {
        if (isMonotonic()) {
            now = log_time(CLOCK_MONOTONIC);
        } else {
            now = log_time(CLOCK_REALTIME);
        }
    }
}
Example #14
0
int OpenDemux( vlc_object_t* p_this )
{
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys;

    const uint8_t *p_peek;
    ssize_t i_peek = vlc_stream_Peek( p_demux->s, &p_peek, 2048 );
    if( unlikely( i_peek <= 32 ) )
        return VLC_EGENERIC;

    const char *psz_xml = (const char *) p_peek;
    size_t i_xml  = i_peek;

    /* Try to probe without xml module/loading the full document */
    char *psz_alloc = NULL;
    switch( GetQWBE(p_peek) )
    {
        /* See RFC 3023 Part 4 */
        case UINT64_C(0xFFFE3C003F007800): /* UTF16 BOM<? */
        case UINT64_C(0xFFFE3C003F007400): /* UTF16 BOM<t */
        case UINT64_C(0xFEFF003C003F0078): /* UTF16 BOM<? */
        case UINT64_C(0xFEFF003C003F0074): /* UTF16 BOM<t */
            psz_alloc = FromCharset( "UTF-16", p_peek, i_peek );
            break;
        case UINT64_C(0x3C003F0078006D00): /* UTF16-LE <?xm */
        case UINT64_C(0x3C003F0074007400): /* UTF16-LE <tt */
            psz_alloc = FromCharset( "UTF-16LE", p_peek, i_peek );
            break;
        case UINT64_C(0x003C003F0078006D): /* UTF16-BE <?xm */
        case UINT64_C(0x003C003F00740074): /* UTF16-BE <tt */
            psz_alloc = FromCharset( "UTF-16BE", p_peek, i_peek );
            break;
        case UINT64_C(0xEFBBBF3C3F786D6C): /* UTF8 BOM<?xml */
        case UINT64_C(0x3C3F786D6C207665): /* UTF8 <?xml ve */
        case UINT64_C(0xEFBBBF3C74742078): /* UTF8 BOM<tt x*/
            break;
        default:
            if(GetDWBE(p_peek) != UINT32_C(0x3C747420)) /* tt node without xml document marker */
                return VLC_EGENERIC;
    }

    if( psz_alloc )
    {
        psz_xml = psz_alloc;
        i_xml = strlen( psz_alloc );
    }

    /* Simplified probing. Valid TTML must have a namespace declaration */
    const char *psz_tt = strnstr( psz_xml, "tt ", i_xml );
    if( !psz_tt || psz_tt == psz_xml ||
        (psz_tt[-1] != ':' && psz_tt[-1] != '<') )
    {
        free( psz_alloc );
        return VLC_EGENERIC;
    }
    else
    {
        const char * const rgsz[] =
        {
            "=\"http://www.w3.org/ns/ttml\"",
            "=\"http://www.w3.org/2004/11/ttaf1\"",
            "=\"http://www.w3.org/2006/04/ttaf1\"",
            "=\"http://www.w3.org/2006/10/ttaf1\"",
        };
        const char *psz_ns = NULL;
        for( size_t i=0; i<ARRAY_SIZE(rgsz) && !psz_ns; i++ )
        {
            psz_ns = strnstr( psz_xml, rgsz[i],
                              i_xml - (psz_tt - psz_xml) );
        }
        free( psz_alloc );
        if( !psz_ns )
            return VLC_EGENERIC;
    }

    p_demux->p_sys = p_sys = calloc( 1, sizeof( *p_sys ) );
    if( unlikely( p_sys == NULL ) )
        return VLC_ENOMEM;

    p_sys->b_first_time = true;
    p_sys->temporal_extent.i_type = TT_TIMINGS_PARALLEL;
    tt_time_Init( &p_sys->temporal_extent.begin );
    tt_time_Init( &p_sys->temporal_extent.end );
    tt_time_Init( &p_sys->temporal_extent.dur );
    p_sys->temporal_extent.begin.base = 0;

    p_sys->p_xml = xml_Create( p_demux );
    if( !p_sys->p_xml )
        goto error;

    p_sys->p_reader = xml_ReaderCreate( p_sys->p_xml, p_demux->s );
    if( !p_sys->p_reader )
        goto error;

#ifndef TTML_DEMUX_DEBUG
    p_sys->p_reader->obj.flags |= OBJECT_FLAGS_QUIET;
#endif

    if( ReadTTML( p_demux ) != VLC_SUCCESS )
        goto error;

    tt_timings_Resolve( (tt_basenode_t *) p_sys->p_rootnode, &p_sys->temporal_extent,
                        &p_sys->times.p_array, &p_sys->times.i_count );

#ifdef TTML_DEMUX_DEBUG
    {
        struct vlc_memstream stream;

        if( vlc_memstream_open( &stream ) )
            goto error;

        tt_time_t t;
        tt_time_Init( &t );
        tt_node_ToText( &stream, (tt_basenode_t*)p_sys->p_rootnode, &t /* invalid */ );

        vlc_memstream_putc( &stream, '\0' );

        if( vlc_memstream_close( &stream ) == VLC_SUCCESS )
        {
            msg_Dbg( p_demux, "%s", stream.ptr );
            free( stream.ptr );
        }
    }
#endif

    p_demux->pf_demux = Demux;
    p_demux->pf_control = Control;

    es_format_t fmt;
    es_format_Init( &fmt, SPU_ES, VLC_CODEC_TTML );
    p_sys->p_es = es_out_Add( p_demux->out, &fmt );
    if( !p_sys->p_es )
        goto error;

    es_format_Clean( &fmt );

    return VLC_SUCCESS;

error:
    CloseDemux( p_demux );

    return VLC_EGENERIC;
}
Example #15
0
int tps_pack_request(sip_msg_t *msg, tps_data_t *ptsd)
{
	hdr_field_t *hdr;
	via_body_t *via;
	rr_t *rr;
	int i;
	int vlen;

	if(ptsd->cp==NULL) {
		ptsd->cp = ptsd->cbuf;
	}
	i = 0;
	for(hdr=msg->h_via1; hdr; hdr=next_sibling_hdr(hdr)) {
		for(via=(struct via_body*)hdr->parsed; via; via=via->next) {
			i++;
			vlen = tps_skip_rw(via->name.s, via->bsize);
			if(ptsd->cp + vlen + 2 >= ptsd->cbuf + TPS_DATA_SIZE) {
				LM_ERR("no more spage to pack via headers\n");
				return -1;
			}
			if(i>1) {
				*ptsd->cp = ',';
				ptsd->cp++;
				if(i>2) {
					ptsd->x_via2.len++;
				}
			}
			memcpy(ptsd->cp, via->name.s, vlen);
			if(i==1) {
				ptsd->x_via1.s = ptsd->cp;
				ptsd->x_via1.len = vlen;
				if(via->branch!=NULL) {
					ptsd->x_vbranch1.s = ptsd->x_via1.s + (via->branch->value.s - via->name.s);
					ptsd->x_vbranch1.len = via->branch->value.len;
				}
			} else {
				if(i==2) {
					ptsd->x_via2.s = ptsd->cp;
				}
				ptsd->x_via2.len += vlen;
			}
			ptsd->cp += vlen;
		}
	}
	LM_DBG("compacted headers - x_via1: [%.*s](%d) - x_via2: [%.*s](%d)"
			" - x_vbranch1: [%.*s](%d)\n",
			ptsd->x_via1.len, ZSW(ptsd->x_via1.s), ptsd->x_via1.len,
			ptsd->x_via2.len, ZSW(ptsd->x_via2.s), ptsd->x_via2.len,
			ptsd->x_vbranch1.len, ZSW(ptsd->x_vbranch1.s), ptsd->x_vbranch1.len);

	i = 0;
	ptsd->a_rr.len = 0;
	for(hdr=msg->record_route; hdr; hdr=next_sibling_hdr(hdr)) {
		if (parse_rr(hdr) < 0) {
			LM_ERR("failed to parse RR\n");
			return -1;
		}

		for(rr =(rr_t*)hdr->parsed; rr; rr=rr->next) {
			i++;
			if(ptsd->cp + rr->nameaddr.uri.len + 4 >= ptsd->cbuf + TPS_DATA_SIZE) {
				LM_ERR("no more spage to pack rr headers\n");
				return -1;
			}
			if(i>1) {
				*ptsd->cp = ',';
				ptsd->cp++;
				ptsd->a_rr.len++;
			}
			*ptsd->cp = '<';
			if(i==1) {
				ptsd->a_rr.s = ptsd->cp;
			}
			ptsd->cp++;
			ptsd->a_rr.len++;

			memcpy(ptsd->cp, rr->nameaddr.uri.s, rr->nameaddr.uri.len);
			if(i==1) {
				ptsd->bs_contact.s = ptsd->cp;
				ptsd->bs_contact.len = rr->nameaddr.uri.len;
				if(strnstr(ptsd->bs_contact.s, ";r2=on",
							ptsd->bs_contact.len)==NULL) {
					LM_DBG("single record routing by proxy\n");
					ptsd->as_contact.s = ptsd->cp;
					ptsd->as_contact.len = rr->nameaddr.uri.len;
				}
			} else {
				if(i==2 && ptsd->as_contact.len==0) {
					LM_DBG("double record routing by proxy\n");
					ptsd->as_contact.s = ptsd->cp;
					ptsd->as_contact.len = rr->nameaddr.uri.len;
				}
			}
			ptsd->a_rr.len += rr->nameaddr.uri.len;
			ptsd->cp += rr->nameaddr.uri.len;
			*ptsd->cp = '>';
			ptsd->cp++;
			ptsd->a_rr.len++;
		}

	}
	LM_DBG("compacted headers - a_rr: [%.*s](%d) - b_rr: [%.*s](%d)\n",
			ptsd->a_rr.len, ZSW(ptsd->a_rr.s), ptsd->a_rr.len,
			ptsd->b_rr.len, ZSW(ptsd->b_rr.s), ptsd->b_rr.len);
	LM_DBG("compacted headers - as_contact: [%.*s](%d) - bs_contact: [%.*s](%d)\n",
			ptsd->as_contact.len, ZSW(ptsd->as_contact.s), ptsd->as_contact.len,
			ptsd->bs_contact.len, ZSW(ptsd->bs_contact.s), ptsd->bs_contact.len);
	return 0;
}
// returns false and sets g_errno on error
bool Title::setTitle ( Xml *xml, Words *words, int32_t maxTitleLen, Query *query,
                       LinkInfo *linkInfo, Url *firstUrl, const char *filteredRootTitleBuf, int32_t filteredRootTitleBufSize,
                       uint8_t contentType, uint8_t langId, int32_t niceness ) {
	// make Msg20.cpp faster if it is just has
	// Msg20Request::m_setForLinkInfo set to true, no need to extricate a title.
	if ( maxTitleLen <= 0 ) {
		return true;
	}

	m_niceness = niceness;
	m_maxTitleLen = maxTitleLen;

	// if this is too big the "first line" algo can be huge!!!
	// and really slow everything way down with a huge title candidate
	int32_t maxTitleWords = 128;

	// assume no title
	reset();

	int32_t NW = words->getNumWords();

	//
	// now get all the candidates
	//

	// . allow up to 100 title CANDIDATES
	// . "as" is the word # of the first word in the candidate
	// . "bs" is the word # of the last word IN the candidate PLUS ONE
	int32_t n = 0;
	int32_t as[MAX_TIT_CANDIDATES];
	int32_t bs[MAX_TIT_CANDIDATES];
	float scores[MAX_TIT_CANDIDATES];
	Words *cptrs[MAX_TIT_CANDIDATES];
	int32_t types[MAX_TIT_CANDIDATES];
	int32_t parent[MAX_TIT_CANDIDATES];

	// record the scoring algos effects
	float  baseScore        [MAX_TIT_CANDIDATES];
	float  noCapsBoost      [MAX_TIT_CANDIDATES];
	float  qtermsBoost      [MAX_TIT_CANDIDATES];
	float  inCommonCandBoost[MAX_TIT_CANDIDATES];

	// reset these
	for ( int32_t i = 0 ; i < MAX_TIT_CANDIDATES ; i++ ) {
		// assume no parent
		parent[i] = -1;
	}

	// xml and words class for each link info, rss item
	Xml   tx[MAX_TIT_CANDIDATES];
	Words tw[MAX_TIT_CANDIDATES];
	int32_t  ti = 0;

	// restrict how many link texts and rss blobs we check for titles
	// because title recs like www.google.com have hundreds and can
	// really slow things down to like 50ms for title generation
	int32_t kcount = 0;
	int32_t rcount = 0;

	//int64_t x = gettimeofdayInMilliseconds();

	// . get every link text
	// . TODO: repeat for linkInfo2, the imported link text
	for ( Inlink *k = NULL; linkInfo && (k = linkInfo->getNextInlink(k)) ; ) {
		// breathe
		QUICKPOLL(m_niceness);
		// fast skip check for link text
		if ( k->size_linkText >= 3 && ++kcount >= 20 ) continue;
		// fast skip check for rss item
		if ( k->size_rssItem > 10 && ++rcount >= 20 ) continue;

		// set Url
		Url u;
		u.set( k->getUrl(), k->size_urlBuf );

		// is it the same host as us?
		bool sh = true;

		// skip if not from same host and should be
		if ( firstUrl->getHostLen() != u.getHostLen() ) {
			sh = false;
		}

		// skip if not from same host and should be
		if ( strncmp( firstUrl->getHost(), u.getHost(), u.getHostLen() ) ) {
			sh = false;
		}

		// get the link text
		if ( k->size_linkText >= 3 ) {
			char *p    = k->getLinkText();
			int32_t  plen = k->size_linkText - 1;
			if ( ! verifyUtf8 ( p , plen ) ) {
				log("title: set4 bad link text from url=%s", k->getUrl());
				continue;
			}

			// now the words.
			if ( !tw[ti].set( k->getLinkText(), k->size_linkText - 1, true, 0 ) ) {
				return false;
			}

			// set the bookends, it is the whole thing
			cptrs   [n] = &tw[ti];
			as      [n] = 0;
			bs      [n] = tw[ti].getNumWords();
			// score higher if same host
			if ( sh ) scores[n] = 1.05;
			// do not count so high if remote!
			else      scores[n] = 0.80;
			// set the type
			if ( sh ) types [n] = TT_LINKTEXTLOCAL;
			else      types [n] = TT_LINKTEXTREMOTE;
			// another candidate
			n++;
			// use xml and words
			ti++;
			// break out if too many already. save some for below.
			if ( n + 30 >= MAX_TIT_CANDIDATES ) break;
		}
		// get the rss item
		if ( k->size_rssItem <= 10 ) continue;
		// . returns false and sets g_errno on error
		// . use a 0 for niceness
		if ( ! k->setXmlFromRSS ( &tx[ti] , 0 ) ) return false;
		// get the word range
		int32_t tslen;
		bool isHtmlEnc;
		char *ts = tx[ti].getRSSTitle ( &tslen , &isHtmlEnc );
		// skip if not in the rss
		if ( ! ts ) continue;
		// skip if empty
		if ( tslen <= 0 ) continue;
		// now set words to that
		if ( !tw[ti].set( ts, tslen, true, 0 ) ) {
			return false;
		}

		// point to that
		cptrs   [n] = &tw[ti];
		as      [n] = 0;
		bs      [n] = tw[ti].getNumWords();
		// increment since we are using it
		ti++;
		// base score for rss title
		if ( sh ) scores[n] = 5.0;
		// if not same host, treat like link text
		else      scores[n] = 2.0;
		// set the type
		if ( sh ) types [n] = TT_RSSITEMLOCAL;
		else      types [n] = TT_RSSITEMREMOTE;
		// advance
		n++;
		// break out if too many already. save some for below.
		if ( n + 30 >= MAX_TIT_CANDIDATES ) break;
	}

	//logf(LOG_DEBUG,"title: took1=%" PRId64,gettimeofdayInMilliseconds()-x);
	//x = gettimeofdayInMilliseconds();

	// . set the flags array
	// . indicates what words are in title candidates already, but
	//   that is set below
	// . up here we set words that are not allowed to be in candidates,
	//   like words that are in a link that is not a self link
	// . alloc for it
	char *flags = NULL;
	char localBuf[10000];

	int32_t  need = words->getNumWords();
	if ( need <= 10000 ) {
		flags = (char *)localBuf;
	} else {
		flags = (char *)mmalloc(need,"TITLEflags");
	}

	if ( ! flags ) {
		return false;
	}

	// clear it
	memset ( flags , 0 , need );

	// check tags in body
	nodeid_t *tids = words->getTagIds();

	// scan to set link text flags
	// loop over all "words" in the html body
	char inLink   = false;
	char selfLink = false;
	for ( int32_t i = 0 ; i < NW ; i++ ) {
		// breathe
		QUICKPOLL(m_niceness);

		// if in a link that is not self link, cannot be in a candidate
		if ( inLink && ! selfLink ) {
			flags[i] |= 0x02;
		}

		// out of a link
		if ( tids[i] == (TAG_A | BACKBIT) ) {
			inLink = false;
		}

		// if not start of <a> tag, skip it
		if ( tids[i] != TAG_A ) {
			continue;
		}

		// flag it
		inLink = true;

		// get the node in the xml
		int32_t xn = words->getNodes()[i];

		// is it a self link?
		int32_t len;
		char *link = xml->getString(xn,"href",&len);

		// . set the url class to this
		// . TODO: use the base url in the doc
		Url u;
		u.set( link, len, true, false );

		// compare
		selfLink = u.equals ( firstUrl );

		// skip if not selfLink
		if ( ! selfLink ) {
			continue;
		}

		// if it is a selflink , check for an "onClick" tag in the
		// anchor tag to fix that Mixx issue for:
		// http://www.npr.org/templates/story/story.php?storyId=5417137

		int32_t  oclen;
		char *oc = xml->getString(xn,"onclick",&oclen);

		if ( ! oc ) {
			oc = xml->getString(xn,"onClick",&oclen);
		}

		// assume not a self link if we see that...
		if ( oc ) {
			selfLink = false;
		}

		// if this <a href> link has a "title" attribute, use that
		// instead! that thing is solid gold.
		int32_t  atlen;
		char *atitle = xml->getString(xn,"title",&atlen);

		// stop and use that, this thing is gold!
		if ( ! atitle || atlen <= 0 ) {
			continue;
		}

		// craziness? ignore it...
		if ( atlen > 400 ) {
			continue;
		}

		// if it contains permanent, permalink or share, ignore it!
		if ( strncasestr ( atitle, "permalink", atlen ) ||
		     strncasestr ( atitle,"permanent", atlen) ||
		     strncasestr ( atitle,"share", atlen) ) {
			continue;
		}

		// do not count the link text as viable
		selfLink = false;

		// aw, dammit
		if ( ti >= MAX_TIT_CANDIDATES ) {
			continue;
		}

		// other dammit
		if ( n >= MAX_TIT_CANDIDATES ) {
			break;
		}

		// ok, process it
		if ( ! tw[ti].set ( atitle, atlen, true, 0 )) {
			return false;
		}

		// set the bookends, it is the whole thing
		cptrs   [n] = &tw[ti];
		as      [n] = 0;
		bs      [n] = tw[ti].getNumWords();
		scores  [n] = 3.0; // not ALWAYS solid gold!
		types   [n] = TT_TITLEATT;

		// we are using the words class
		ti++;

		// advance
		n++;

		// break out if too many already. save some for below.
		if ( n + 20 >= MAX_TIT_CANDIDATES ) {
			break;
		}
	}

	//logf(LOG_DEBUG,"title: took2=%" PRId64,gettimeofdayInMilliseconds()-x);
	//x = gettimeofdayInMilliseconds();

	//int64_t *wids = WW->getWordIds();
	// . find the last positive scoring guy
	// . do not consider title candidates after "r" if "r" is non-zero
	// . FIXES http://larvatusprodeo.net/2009/01/07/partisanship-politics-and-participation/

	// the candidate # of the title tag
	int32_t tti = -1;

	// allow up to 4 tags from each type
	char table[512];

	// sanity check
	if ( getNumXmlNodes() > 512 ) { char *xx=NULL;*xx=0; }

	// clear table counts
	memset ( table , 0 , 512 );

	// the first word
	char *wstart = NULL;
	if ( NW > 0 ) {
		wstart = words->getWord(0);
	}

	// loop over all "words" in the html body
	for ( int32_t i = 0 ; i < NW ; i++ ) {
		// come back up here if we encounter another "title-ish" tag
		// within our first alleged "title-ish" tag
	subloop:
		// stop after 30k of text
		if ( words->getWord(i) - wstart > 200000 ) {
			break; // 1106
		}

		// get the tag id minus the back tag bit
		nodeid_t tid = tids[i] & BACKBITCOMP;


		// pen up and pen down for these comment like tags
		if ( tid == TAG_SCRIPT || tid == TAG_STYLE ) {
			// ignore "titles" in script or style tags
			if ( ! (tids[i] & BACKBIT) ) {
				continue;
			}
		}

		/// @todo ALC we should allow more tags than just title/link
		// skip if not a good tag.
		if (tid != TAG_TITLE && tid != TAG_A) {
			continue;
		}

		// must NOT be a back tag
		if ( tids[i] & BACKBIT ) {
			continue;
		}

		// skip if we hit our limit
		if ( table[tid] >= 4 ) {
			continue;
		}

		// skip over tag/word #i
		i++;

		// no words in links, unless it is a self link
		if ( i < NW && (flags[i] & 0x02) ) {
			continue;
		}

		// the start should be here
		int32_t start = -1;

		// do not go too far
		int32_t max = i + 200;

		// find the corresponding back tag for it
		for (  ; i < NW && i < max ; i++ ) {
			// hey we got it, BUT we got no alnum word first
			// so the thing was empty, so loop back to subloop
			if ( (tids[i] & BACKBITCOMP) == tid  &&   
			     (tids[i] & BACKBIT    ) && 
			     start == -1 ) {
				goto subloop;
			}

			// if we hit another title-ish tag, loop back up
			if ( (tids[i] & BACKBITCOMP) == TAG_TITLE || (tids[i] & BACKBITCOMP) == TAG_A ) {
				// if no alnum text, restart at the top
				if ( start == -1 ) {
					goto subloop;
				}

				// otherwise, break out and see if title works
				break;
			}

			// if we hit a breaking tag...
			if ( isBreakingTagId ( tids[i] & BACKBITCOMP ) &&
			     // do not consider <span> tags breaking for 
			     // our purposes. i saw a <h1><span> setup before.
			     tids[i] != TAG_SPAN ) {
				break;
			}

			// skip if not alnum word
			if ( ! words->isAlnum(i) ) {
				continue;
			}

			// if we hit an alnum word, break out
			if ( start == -1 ) {
				start = i;
			}
		}

		// if no start was found, must have had a 0 score in there
		if ( start == -1 ) {
			continue;
		}

		// if we exhausted the doc, we are done
		if ( i >= NW ) {
			break;
		}

		// skip if way too big!
		if ( i >= max ) {
			continue;
		}

		// if was too long do not consider a title
		if ( i - start > 300 ) {
			continue;
		}

		// . skip if too many bytes
		// . this does not include the length of word #i, but #(i-1)
		if ( words->getStringSize ( start , i ) > 1000 ) {
			continue;
		}

		// when using pdftohtml, the title tag is the filename when PDF property does not have title tag
		if ( tid == TAG_TITLE && contentType == CT_PDF ) {
			// skip if title == '/in.[0-9]*'
			char* title_start = words->getWord(start);
			char* title_end = words->getWord(i);
			size_t title_size = title_end - title_start;
			const char* result = strnstr( title_start, "/in.", title_size );
			if (result != NULL) {
				char* endp = NULL;
				// do some further verification to avoid screwing up title
				if ((strtoll(result + 4, &endp, 10) > 0) && (endp == title_end)) {
					continue;
				}
			}
		}

		// count it
		table[tid]++;

		// max it out if we are positive scoring. stop after the
		// first positive scoring guy in a section. this might
		// hurt the "Hamlet" thing though...

		// store a point to the title tag guy. Msg20.cpp needs this
		// because the zak's proximity algo uses it in Summary.cpp
		// and in Msg20.cpp

		// only get the first one! often the 2nd on is in an iframe!! which we now expand into here.
		if ( tid == TAG_TITLE && m_titleTagStart == -1 ) {
			m_titleTagStart = start;
			m_titleTagEnd   = i;

			// save the candidate # because we always use this
			// as the title if we are a root
			if ( tti < 0 ) {
				tti = n;
			}
		}

		// point to words class of the body that was passed in to us
		cptrs[n] = words;
		as[n] = start;
		bs[n] = i;
		if ( tid == TAG_B ) {
			types[n] = TT_BOLDTAG;
			scores[n] = 1.0;
		} else if ( tid == TAG_H1 ) {
			types[n] = TT_HTAG;
			scores[n] = 1.8;
		} else if ( tid == TAG_H2 ) {
			types[n] = TT_HTAG;
			scores[n] = 1.7;
		} else if ( tid == TAG_H3 ) {
			types[n] = TT_HTAG;
			scores[n] = 1.6;
		} else if ( tid == TAG_TITLE ) {
			types[n] = TT_TITLETAG;
			scores[n] = 3.0;
		} else if ( tid == TAG_DIV ) {
			types[n] = TT_DIVTAG;
			scores[n] = 1.0;
		} else if ( tid == TAG_TD ) {
			types[n] = TT_TDTAG;
			scores[n] = 1.0;
		} else if ( tid == TAG_P ) {
			types[n] = TT_PTAG;
			scores[n] = 1.0;
		} else if ( tid == TAG_FONT ) {
			types[n] = TT_FONTTAG;
			scores[n] = 1.0;
		} else if ( tid == TAG_A ) {
			types[n] = TT_ATAG;
			// . self link is very powerful BUT
			//   http://www.npr.org/templates/story/story.php?storyId=5417137
			//   doesn't use it right! so use
			//   1.3 instead of 3.0. that has an "onClick" thing in the
			//   <a> tag, so check for that!
			// this was bad for
			// http://www.spiritualwoman.net/?cat=191
			// so i am demoting from 3.0 to 1.5
			scores[n] = 1.5;
		}

		// count it
		n++;

		// start loop over at tag #i, for loop does an i++, so negate
		// that so this will work
		i--;

		// break out if too many already. save some for below.
		if ( n + 10 >= MAX_TIT_CANDIDATES ) {
			break;
		}
	}

	//logf(LOG_DEBUG,"title: took3=%" PRId64,gettimeofdayInMilliseconds()-x);
	//x = gettimeofdayInMilliseconds();

	// to handle text documents, throw in the first line of text
	// as a title candidate, just make the score really low
	bool textDoc = (contentType == CT_UNKNOWN || contentType == CT_TEXT);

	if (textDoc) {
		// make "i" point to first alphabetical word in the document
		int32_t i ;

		for ( i = 0 ; i < NW && !words->isAlpha(i) ; i++);

		// if we got a first alphabetical word, then assume that to be the start of our title
		if ( i < NW && n < MAX_TIT_CANDIDATES ) {
			// first word in title is "t0"
			int32_t t0 = i;
			// find end of first line
			int32_t numWords = 0;

			// set i to the end now. we MUST find a \n to terminate the
			// title, otherwise we will not have a valid title
			while (i < NW && numWords < maxTitleWords && (words->isAlnum(i) || !words->hasChar(i, '\n'))) {
				if(words->isAlnum(i)) {
					numWords++;
				}

				++i;
			}

			// "t1" is the end
			int32_t t1 = -1;

			// we must have found our \n in order to set "t1"
			if (i <= NW && numWords < maxTitleWords ) {
				t1 = i;
			}

			// set the ptrs
			cptrs   [n] =  words;

			// this is the last resort i guess...
			scores  [n] =  0.5;
			types   [n] =  TT_FIRSTLINE;
			as      [n] =  t0;
			bs      [n] =  t1;

			// add it as a candidate if t0 and t1 were valid
			if (t0 >= 0 && t1 > t0) {
				n++;
			}
		}
	}

	//logf(LOG_DEBUG,"title: took4=%" PRId64,gettimeofdayInMilliseconds()-x);
	//x = gettimeofdayInMilliseconds();

	{
		// now add the last url path to contain underscores or hyphens
		char *pstart = firstUrl->getPath();

		// get first url
		Url *fu = firstUrl;

		// start at the end
		char *p = fu->getUrl() + fu->getUrlLen();

		// end pointer
		char *pend = NULL;

		// come up here for each path component
		while ( p >= pstart ) {
			// save end
			pend = p;

			// skip over /
			if ( *p == '/' ) {
				p--;
			}

			// now go back to next /
			int32_t count = 0;
			for ( ; p >= pstart && *p !='/' ; p-- ) {
				if ( *p == '_' || *p == '-' ) {
					count++;
				}
			}

			// did we get it?
			if ( count > 0 ) {
				break;
			}
		}

		// did we get any?
		if ( p > pstart && n < MAX_TIT_CANDIDATES ) {
			// now set words to that
			if ( ! tw[ti].set ( p, (pend - p), true, 0 )) {
				return false;
			}

			// point to that
			cptrs   [n] = &tw[ti];
			as      [n] = 0;
			bs      [n] = tw[ti].getNumWords();
			scores  [n] = 1.0;
			types   [n] = TT_URLPATH;

			// increment since we are using it
			ti++;

			// advance
			n++;
		}
	}

	// save old n
	int32_t oldn = n;

	// . do not split titles if we are a root url maps.yahoo.com was getting "Maps" for the title
	if ( firstUrl->isRoot() ) {
		oldn = -2;
	}

	// point to list of \0 separated titles
	const char *rootTitleBuf    = NULL;
	const char *rootTitleBufEnd = NULL;

	// get the root title if we are not root!
	if (filteredRootTitleBuf) {
#ifdef _VALGRIND_
		VALGRIND_CHECK_MEM_IS_DEFINED(filteredRootTitleBuf,filteredRootTitleBufSize);
#endif
		// point to list of \0 separated titles
		rootTitleBuf    = filteredRootTitleBuf;
		rootTitleBufEnd =  filteredRootTitleBuf + filteredRootTitleBufSize;
	}

	{
		Matches m;
		if ( rootTitleBuf && query ) {
			m.setQuery ( query );
		}

		// convert into an array
		int32_t nr = 0;
		const char *pr = rootTitleBuf;
		const char *rootTitles[20];
		int32_t  rootTitleLens[20];

		// loop over each root title segment
		for ( ; pr && pr < rootTitleBufEnd ; pr += strnlen(pr,rootTitleBufEnd-pr) + 1 ) {
			// if we had a query...
			if ( query ) {
				// reset it
				m.reset();

				// see if root title segment has query terms in it
				m.addMatches ( const_cast<char*>(pr), strnlen(pr,rootTitleBufEnd-pr), MF_TITLEGEN, m_niceness );

				// if matches query, do NOT add it, we only add it for
				// removing from the title of the page...
				if ( m.getNumMatches() ) {
					continue;
				}
			}
			// point to it. it should start with an alnum already
			// since it is the "filtered" list of root titles...
			// if not, fix it in xmldoc then.
			rootTitles   [nr] = pr;
			rootTitleLens[nr] = gbstrlen(pr);
			// advance
			nr++;
			// no breaching
			if ( nr >= 20 ) break;
		}

		// now split up candidates in children candidates by tokenizing
		// using :, | and - as delimters.
		// the hyphen must have a space on at least one side, so "cd-rom" does
		// not create a pair of tokens...
		// FIX: for the title:
		// Best Careers 2009: Librarian - US News and World Report
		// we need to recognize "Best Careers 2009: Librarian" as a subtitle
		// otherwise we don't get it as the title. so my question is are we
		// going to have to do all the permutations at some point? for now
		// let's just add in pairs...
		for ( int32_t i = 0 ; i < oldn && n + 3 < MAX_TIT_CANDIDATES ; i++ ) {
			// stop if no root title segments
			if ( nr <= 0 ) break;
			// get the word info
			Words *w = cptrs[i];
			int32_t   a = as[i];
			int32_t   b = bs[i];
			// init
			int32_t lasta = a;
			char prev  = false;
			// char length in bytes
			//int32_t charlen = 1;
			// see how many we add
			int32_t added = 0;
			char *skipTo = NULL;
			bool qualified = true;
			// . scan the words looking for a token
			// . sometimes the candidates end in ": " so put in "k < b-1"
			// . made this from k<b-1 to k<b to fix
			//   "Hot Tub Time Machine (2010) - IMDb" to strip IMDb
			for ( int32_t k = a ; k < b && n + 3 < MAX_TIT_CANDIDATES; k++){
				// get word
				char *wp = w->getWord(k);
				// skip if not alnum
				if ( ! w->isAlnum(k) ) {
					// in order for next alnum word to
					// qualify for "clipping" if it matches
					// the root title, there has to be more
					// than just spaces here, some punct.
					// otherwise title
					// "T. D. Jakes: Biography from Answers.com"
					// becomes
					// "T. D. Jakes: Biography from"
					qualified=isWordQualified(wp,w->getWordLen(k));
					continue;
				}
				// gotta be qualified!
				if ( ! qualified ) continue;
				// skip if in root title
				if ( skipTo && wp < skipTo ) continue;
				// does this match any root page title segments?
				int32_t j;
				for ( j = 0 ; j < nr ; j++ ) {
					// . compare to root title
					// . break out if we matched!
					if ( ! strncmp( wp, rootTitles[j], rootTitleLens[j] ) ) {
						break;
					}
				}

				// if we did not match a root title segment,
				// keep on chugging
				if ( j >= nr ) continue;
				// . we got a root title match!
				// . skip over
				skipTo = wp + rootTitleLens[j];
				// must land on qualified punct then!!
				int32_t e = k+1;
				for ( ; e<b && w->getWord(e)<skipTo ; e++ );
				// ok, word #e must be a qualified punct
				if ( e<b &&
				     ! isWordQualified(w->getWord(e),w->getWordLen(e)))
					// assume no match then!!
					continue;
				// if we had a previous guy, reset the end of the
				// previous candidate
				if ( prev ) {
					bs[n-2] = k;
					bs[n-1] = k;
				}
				// . ok, we got two more candidates
				// . well, only one more if this is not the 1st time
				if ( ! prev ) {
					cptrs   [n] = cptrs   [i];
					scores  [n] = scores  [i];
					types   [n] = types   [i];
					as      [n] = lasta;
					bs      [n] = k;
					parent  [n] = i;
					n++;
					added++;
				}
				// the 2nd one
				cptrs   [n] = cptrs   [i];
				scores  [n] = scores  [i];
				types   [n] = types   [i];
				as      [n] = e + 1;
				bs      [n] = bs      [i];
				parent  [n] = i;
				n++;
				added++;

				// now add in the last pair as a whole token
				cptrs   [n] = cptrs   [i];
				scores  [n] = scores  [i];
				types   [n] = types   [i];
				as      [n] = lasta;
				bs      [n] = bs      [i];
				parent  [n] = i;
				n++;
				added++;

				// nuke the current candidate then since it got
				// split up to not contain the root title...
				//cptrs[i] = NULL;

				// update this
				lasta = k+1;

				// if we encounter another delimeter we will have to revise bs[n-1], so note that
				prev = true;
			}

			// nuke the current candidate then since it got
			// split up to not contain the root title...
			if ( added ) {
				scores[i] = 0.001;
				//cptrs[i] = NULL;
			}

			// erase the pair if that there was only one token
			if ( added == 3 ) n--;
		}
	}

	for ( int32_t i = 0 ; i < n ; i++ ) baseScore[i] = scores[i];
	
	//
	// . now punish by 0.85 for every lower case non-stop word it has
	// . reward by 1.1 if has a non-stopword in the query
	//
	for ( int32_t i = 0 ; i < n ; i++ ) {
		// point to the words
		Words *w = cptrs[i];

		// skip if got nuked above
		if ( ! w ) {
			continue;
		}

		// the word ptrs
		char **wptrs = w->getWordPtrs();

		// skip if empty
		if ( w->getNumWords() <= 0 ) {
			continue;
		}

		// get the word boundaries
		int32_t a = as[i];
		int32_t b = bs[i];

		// record the boosts
		float ncb = 1.0;
		float qtb = 1.0;

		// a flag
		char uncapped = false;

		// scan the words in this title candidate
		for ( int32_t j = a ; j < b ; j++ ) {
			// skip stop words
			if ( w->isQueryStopWord( j, langId ) ) {
				continue;
			}

			// punish if uncapitalized non-stopword
			if ( ! w->isCapitalized(j) ) {
				uncapped = true;
			}

			// skip if no query
			if ( ! query ) {
				continue;
			}

			int64_t wid = w->getWordId(j);

			// reward if in the query
			if ( query->getWordNum(wid) >= 0 ) {
				qtb       *= 1.5;
				scores[i] *= 1.5;
			}
		}

		// . only punish once if missing a capitalized word hurts us for:
		//   http://content-uk.cricinfo.com/ausvrsa2008_09/engine/current/match/351682.html
		if ( uncapped ) {
			ncb *= 1.00;
			scores[i] *= 1.00;
		}

		// punish if a http:// title thingy
		char *s = wptrs[a];
		int32_t size = w->getStringSize(a,b);
		if ( size > 9 && memcmp("http://", s, 7) == 0 ) {
			ncb *= .10;
		}
		if ( size > 14 && memcmp("h\0t\0t\0p\0:\0/\0/", s, 14) == 0 ) {
			ncb *= .10;
		}

		// set these guys
		scores[i] *= ncb;

		noCapsBoost[i]  = ncb;
		qtermsBoost[i]  = qtb;
	}

	// . now compare each candidate to the other candidates
	// . give a boost if matches
	for ( int32_t i = 0 ; i < n ; i++ ) {
		// point to the words
		Words *w1 = cptrs[i];

		// skip if got nuked above
		if ( ! w1 ) {
			continue;
		}

		int32_t a1 = as[i];
		int32_t b1 = bs[i];

		// reset some flags
		char localFlag1 = 0;
		char localFlag2 = 0;

		// record the boost
		float iccb = 1.0;

		// total boost
		float total = 1.0;

		// to each other candidate
		for ( int32_t j = 0 ; j < n ; j++ ) {
			// not to ourselves
			if ( j == i ) {
				continue;
			}

			// or our derivatives
			if ( parent[j] == i ) {
				continue;
			}

			// or derivates to their parent
			if ( parent[i] == j ) {
				continue;
			}

			// only check parents now. do not check kids.
			// this was only for when doing percent contained
			// not getSimilarity() per se
			//if ( parent[j] != -1 ) continue;

			// TODO: do not accumulate boosts from a parent
			// and its kids, subtitles...
			//
			// do not compare type X to type Y
			if ( types[i] == TT_TITLETAG ) {
				if ( types[j] == TT_TITLETAG ) {
					continue;
				}
			}

			// do not compare a div candidate to another div cand
			// http://friendfeed.com/foxiewire?start=30
			// likewise, a TD to another TD
			// http://content-uk.cricinfo.com/ausvrsa2008_09/engine/match/351681.html
			// ... etc.
			if ( types[i] == TT_BOLDTAG ||
			     types[i] == TT_HTAG    ||
			     types[i] == TT_DIVTAG  ||
			     types[i] == TT_TDTAG   ||
			     types[i] == TT_FONTTAG    ) {
				if ( types[j] == types[i] ) continue;
			}
			// . do not compare one kid to another kid
			// . i.e. if we got "x | y" as a title and "x | z"
			//   as a link text, it will emphasize "x" too much
			//   http://content-uk.cricinfo.com/ausvrsa2008_09/engine/current/match/351682.html
			if ( parent[j] != -1 && parent[i] != -1 ) continue;

			// . body type tags are mostly mutually exclusive
			// . for the legacy.com url mentioned below, we have
			//   good stuff in <td> tags, so this hurts us...
			// . but for the sake of 
			//   http://larvatusprodeo.net/2009/01/07/partisanship-politics-and-participation/
			//   i put bold tags back

			if ( types[i] == TT_LINKTEXTLOCAL ) {
				if ( types[j] == TT_LINKTEXTLOCAL ) continue;
			}
			if ( types[i] == TT_RSSITEMLOCAL ) {
				if ( types[j] == TT_RSSITEMLOCAL ) continue;
			}

			// only compare to one local link text for each i
			if ( types[j] == TT_LINKTEXTLOCAL && localFlag1 ) {
				continue;
			}
			if ( types[j] == TT_RSSITEMLOCAL  && localFlag2 ) {
				continue;
			}
			if ( types[j] == TT_LINKTEXTLOCAL ) {
				localFlag1 = 1;
			}
			if ( types[j] == TT_RSSITEMLOCAL  ) {
				localFlag2 = 1;
			}

			// not link title attr to link title attr either
			// fixes http://www.spiritualwoman.net/?cat=191
			if ( types[i] == TT_TITLEATT &&
			     types[j] == TT_TITLEATT )
				continue;

			// get our words
			Words *w2 = cptrs[j];

			// skip if got nuked above
			if ( ! w2 ) continue;
			int32_t   a2 = as   [j];
			int32_t   b2 = bs   [j];

			// how similar is title #i to title #j ?
			float fp = getSimilarity ( w2 , a2 , b2 , w1 , a1 , b1 );

			// error?
			if ( fp == -1.0 ) return false;

			// custom boosting...
			float boost = 1.0;
			if      ( fp >= .95 ) boost = 3.0;
			else if ( fp >= .90 ) boost = 2.0;
			else if ( fp >= .85 ) boost = 1.5;
			else if ( fp >= .80 ) boost = 1.4;
			else if ( fp >= .75 ) boost = 1.3;
			else if ( fp >= .70 ) boost = 1.2;
			else if ( fp >= .60 ) boost = 1.1;
			else if ( fp >= .50 ) boost = 1.08;
			else if ( fp >= .40 ) boost = 1.04;

			// limit total
			total *= boost;
			if ( total > 100.0 ) break;
			// if you are matching the url path, that is pretty 
			// good so give more!
			// actually, that would hurt:
			// http://michellemalkin.com/2008/12/29/gag-worthy/

			// custom boosting!
			if ( fp > 0.0 && g_conf.m_logDebugTitle )
				logf(LOG_DEBUG,"title: i=%" PRId32" j=%" PRId32" fp=%.02f "
				     "b=%.02f", i,j,fp,boost);
			// apply it
			scores[i] *= boost;

			iccb      *= boost;
		}

		inCommonCandBoost[i] = iccb;
	}

	//logf(LOG_DEBUG,"title: took7=%" PRId64,gettimeofdayInMilliseconds()-x);
	//x = gettimeofdayInMilliseconds();


	// loop over all n candidates
	for ( int32_t i = 0 ; i < n ; i++ ) {
		// skip if not in the document body
		if ( cptrs[i] != words ) continue;
		// point to the words
		int32_t       a1    = as   [i];
		int32_t       b1    = bs   [i];

		// . loop through this candidates words
		// . TODO: use memset here?
		for ( int32_t j = a1 ; j <= b1 && j < NW ; j++ ) {
			// flag it
			flags[j] |= 0x01;
		}
	}

	// free our stuff
	if ( flags!=localBuf ) {
		mfree (flags, need, "TITLEflags");
	}

	// now get the highest scoring candidate title
	float max    = -1.0;
	int32_t  winner = -1;
	for ( int32_t i = 0 ; i < n ; i++ ) {
		// skip if got nuked
		if ( ! cptrs[i] ) {
			continue;
		}

		if ( winner != -1 && scores[i] <= max ) {
			continue;
		}

		// url path's cannot be titles in and of themselves
		if ( types[i] == TT_URLPATH ) {
			continue;
		}

		// skip if empty basically, like if title was exact
		// copy of root, then the whole thing got nuked and
		// some empty string added, where a > b
		if ( as[i] >= bs[i] ) {
			continue;
		}

		// got one
		max = scores[i];

		// save it
		winner = i;
	}

	// if we are a root, always pick the title tag as the title
	if ( oldn == -2 && tti >= 0 ) {
		winner = tti;
	}

	// if no winner, all done. no title
	if ( winner == -1 ) {
		// last resort use file name
		if ((contentType == CT_PDF) && (firstUrl->getFilenameLen() != 0)) {
			Words w;
			w.set(firstUrl->getFilename(), firstUrl->getFilenameLen(), true);
			if (!copyTitle(&w, 0, w.getNumWords())) {
				return false;
			}
		}
		return true;
	}

	// point to the words class of the winner
	Words *w = cptrs[winner];
	// skip if got nuked above
	if ( ! w ) { char *xx=NULL;*xx=0; }

	// need to make our own Pos class if title not from body
	Pos  tp;
	if ( w != words ) {
		// set "Scores" ptr to NULL. we assume all are positive scores
		if ( ! tp.set ( w ) ) {
			return false;
		}
	}

	// the string ranges from word #a up to and including word #b
	int32_t a = as[winner];
	int32_t b = bs[winner];
	// sanity check
	if ( a < 0 || b > w->getNumWords() ) { char*xx=NULL;*xx=0; }

	// save the title
	if ( ! copyTitle(w, a, b) ) {
		return false;
	}

	/*
	// debug logging
	SafeBuf sb;
	SafeBuf *pbuf = &sb;

	log("title: candidates for %s",xd->getFirstUrl()->getUrl() );

	pbuf->safePrintf("<div stype=\"border:1px solid black\">");
	pbuf->safePrintf("<b>***Finding Title***</b><br>\n");

	pbuf->safePrintf("<table cellpadding=5 border=2><tr>"
			 "<td colspan=20><center><b>Title Generation</b>"
			 "</center></td>"
			 "</tr>\n<tr>"
			 "<td>#</td>"
			 "<td>type</td>"
			 "<td>parent</td>"
			 "<td>base score</td>"
			 "<td>format penalty</td>"
			 "<td>query term boost</td>"
			 "<td>candidate intersection boost</td>"
			 "<td>FINAL SCORE</td>"
			 "<td>title</td>"
			 "</tr>\n" );
			 

	// print out all candidates
	for ( int32_t i = 0 ; i < n ; i++ ) {
		char *ts = "unknown";
		if ( types[i] == TT_LINKTEXTLOCAL  ) ts = "local inlink text";
		if ( types[i] == TT_LINKTEXTREMOTE ) ts = "remote inlink text";
		if ( types[i] == TT_RSSITEMLOCAL   ) ts = "local rss title";
		if ( types[i] == TT_RSSITEMREMOTE  ) ts = "remote rss title";
		if ( types[i] == TT_BOLDTAG        ) ts = "bold tag";
		if ( types[i] == TT_HTAG           ) ts = "header tag";
		if ( types[i] == TT_TITLETAG       ) ts = "title tag";
		if ( types[i] == TT_FIRSTLINE      ) ts = "first line in text";
		if ( types[i] == TT_FONTTAG        ) ts = "font tag";
		if ( types[i] == TT_ATAG           ) ts = "anchor tag";
		if ( types[i] == TT_DIVTAG         ) ts = "div tag";
		if ( types[i] == TT_TDTAG          ) ts = "td tag";
		if ( types[i] == TT_PTAG           ) ts = "p tag";
		if ( types[i] == TT_URLPATH        ) ts = "url path";
		if ( types[i] == TT_TITLEATT       ) ts = "title attribute";
		// get the title
		pbuf->safePrintf(
				 "<tr>"
				 "<td>#%" PRId32"</td>"
				 "<td><nobr>%s</nobr></td>"
				 "<td>%" PRId32"</td>"
				 "<td>%0.2f</td>" // baseScore
				 "<td>%0.2f</td>"
				 "<td>%0.2f</td>"
				 "<td>%0.2f</td>"
				 "<td>%0.2f</td>"
				 "<td>",
				 i,
				 ts ,
				 parent[i],
				 baseScore[i],
				 noCapsBoost[i],
				 qtermsBoost[i],
				 inCommonCandBoost[i],
				 scores[i]);
		// ptrs
		Words *w = cptrs[i];
		int32_t   a = as[i];
		int32_t   b = bs[i];
		// skip if no words
		if ( w->getNumWords() <= 0 ) continue;
		// the word ptrs
		char **wptrs = w->getWordPtrs();
		// string ptrs
		char *ptr  = wptrs[a];//w->getWord(a);
		int32_t  size = w->getStringSize(a,b);
		// it is utf8
		pbuf->safeMemcpy ( ptr , size );
		// end the line
		pbuf->safePrintf("</td></tr>\n");
	}

	pbuf->safePrintf("</table>\n<br>\n");

	// log these for now
	log("title: %s",sb.getBufStart());
	*/

	return true;

}
Example #17
0
int db_input_wrapper(char* buf, int max_size, int db)
{
  int retval=0;
  int c=0;
  int err=0;
  int* domd=NULL;
  url_t* db_url=NULL;
#ifdef WITH_MHASH
  char* tmp=NULL;
  MHASH* md=NULL;
  void* key=NULL;
  int keylen;
#endif
  FILE** db_filep=NULL;
#ifdef WITH_ZLIB
  gzFile* db_gzp=NULL;
#endif
  switch(db) {
  case DB_OLD: {
    db_url=conf->db_in_url;
    
    domd=&(conf->do_dboldmd);
#ifdef WITH_MHASH
    md=&(conf->dboldmd);
#endif
    
    db_filep=&(conf->db_in);
    
#ifdef WITH_ZLIB
    db_gzp=&(conf->db_gzin);
#endif
    break;
  }
  case DB_NEW: {
    db_url=conf->db_new_url;
    
    domd=&(conf->do_dbnewmd);
#ifdef WITH_MHASH
    md=&(conf->dbnewmd);
#endif
    
    db_filep=&(conf->db_new);
    
#ifdef WITH_ZLIB
    db_gzp=&(conf->db_gznew);
#endif
    break;
  }
  }

#ifdef WITH_CURL
  switch (db_url->type) {
  case url_http:
  case url_https:
  case url_ftp: {
    retval=url_fread(buf,1,max_size,(URL_FILE *)*db_filep);
    break;
  } 
  default:
#endif /* WITH CURL */


  /* Read a character at a time until we are doing md */
#ifdef WITH_ZLIB
  if((*db_gzp==NULL)&&(*domd)){
    retval=fread(buf,1,max_size,*db_filep);
  }
  if((*db_gzp!=NULL)&&(*domd)){
    if(gzeof(*db_gzp)){
      retval=0;
      buf[0]='\0';
    }else {
      if((retval=gzread(*db_gzp,buf,max_size))<0){
	error(0,_("gzread() failed: gzerr=%s!\n"),gzerror(*db_gzp,&err));
	retval=0;
	buf[0]='\0';
      } else {
	/* gzread returns 0 even if uncompressed bytes were read*/
	error(240,"nread=%d,strlen(buf)=%lu,errno=%s,gzerr=%s\n",
              retval,(unsigned long)strnlen((char*)buf, max_size),
              strerror(errno),gzerror(*db_gzp,&err));
	if(retval==0){
	  retval=strnlen((char*)buf, max_size);
	}
      }
    }
  }
  if((*db_gzp!=NULL)&&!(*domd)){
    c=gzgetc(*db_gzp);
    retval= (c==EOF) ? 0 : (buf[0] = c,1);
  }
  if((*db_gzp==NULL)&&!(*domd)){
    c=fgetc(*db_filep);
    if(c==(unsigned char)'\037'){
      c=fgetc(*db_filep);
      if(c==(unsigned char)'\213'){
	/* We got gzip header. */
	error(255,"Got Gzip header. Handling..\n");
	lseek(fileno(*db_filep),0L,SEEK_SET);
	*db_gzp=gzdopen(fileno(*db_filep),"rb");
	c=gzgetc(*db_gzp);
	error(255,"First character after gzip header is: %c(%#X)\n",c,c);
  if(c==-1) {
    int xx;
	  error(0,"Error reading gzipped file: %s\n",gzerror(*db_gzp,&xx));
    exit(EXIT_FAILURE);
  }
      }else {
	/* False alarm */
	ungetc(c,*db_filep);
      }
    }
    retval= (c==EOF) ? 0 : (buf[0] = c,1);
  }

#else /* WITH_ZLIB */
#ifdef WITH_MHASH
  if(*domd){
    retval=fread(buf,1,max_size,*db_filep);
  }else {
    c=fgetc(*db_filep);
    retval= (c==EOF) ? 0 : (buf[0] = c,1);
  }
#else /* WITH_MHASH */
  retval=fread(buf,1,max_size,*db_filep);
#endif /* WITH_MHASH */ 
#endif /* WITH_ZLIB */

#ifdef WITH_MHASH    
  if(*domd){
    if(!*md){
      if((key=get_db_key())!=NULL){
	keylen=get_db_key_len();
	
	if( (*md=
	     mhash_hmac_init(conf->dbhmactype,
			     key,
			     keylen,
			     mhash_get_hash_pblock(conf->dbhmactype)))==
	    MHASH_FAILED){
	  error(0, "mhash_hmac_init() failed for db check. Aborting\n");
	  exit(EXIT_FAILURE);
	}
      } else {
	*domd=0;
      }
    }
    /* FIXME This does not handle the case that @@end_config is on 
       buffer boundary. */
    if (*domd!=0) {
      if((tmp=strnstr(buf,"@@end_db",retval))!=NULL){
	/* We have end of db don't feed the last line to mhash */
	mhash(*md,(void*)buf,tmp-buf);
	/* We don't want to come here again after the *md has been deinited 
	   by db_readline_file() */
	*domd=0;
      } else {
	mhash(*md,(void*)buf,retval);
      }
    }
  }
#endif

#ifdef WITH_CURL
  }
#endif /* WITH CURL */
  return retval;
}
Example #18
0
void stm401_irq_wake_work_func(struct work_struct *work)
{
    int err;
    unsigned short irq_status;
    u32 irq2_status;
    uint8_t irq3_status;
    struct stm401_data *ps_stm401 = container_of(work,
                                    struct stm401_data, irq_wake_work);

    dev_dbg(&ps_stm401->client->dev, "stm401_irq_wake_work_func\n");
    mutex_lock(&ps_stm401->lock);

    if (ps_stm401->mode == BOOTMODE)
        goto EXIT_NO_WAKE;

    /* This is to handle the case of receiving an interrupt after
       suspend_late, but before interrupts were globally disabled. If this
       is the case, interrupts might be disabled now, so we cannot handle
       this at this time. suspend_noirq will return BUSY if this happens
       so that we can handle these interrupts. */
    if (ps_stm401->ignore_wakeable_interrupts) {
        dev_info(&ps_stm401->client->dev,
                 "Deferring interrupt work\n");
        ps_stm401->ignored_interrupts++;
        goto EXIT_NO_WAKE;
    }

    stm401_wake(ps_stm401);

    /* read interrupt mask register */
    stm401_cmdbuff[0] = WAKESENSOR_STATUS;
    err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2);
    if (err < 0) {
        dev_err(&ps_stm401->client->dev, "Reading from stm401 failed\n");
        goto EXIT;
    }
    irq_status = (stm401_readbuff[IRQ_WAKE_MED] << 8)
                 | stm401_readbuff[IRQ_WAKE_LO];

    /* read algorithm interrupt status register */
    stm401_cmdbuff[0] = ALGO_INT_STATUS;
    err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 3);
    if (err < 0) {
        dev_err(&ps_stm401->client->dev, "Reading from stm401 failed\n");
        goto EXIT;
    }
    irq2_status = (stm401_readbuff[IRQ_WAKE_HI] << 16) |
                  (stm401_readbuff[IRQ_WAKE_MED] << 8) |
                  stm401_readbuff[IRQ_WAKE_LO];

    /* read generic interrupt register */
    stm401_cmdbuff[0] = GENERIC_INT_STATUS;
    err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1);
    if (err < 0) {
        dev_err(&ps_stm401->client->dev, "Reading from stm failed\n");
        goto EXIT;
    }
    irq3_status = stm401_readbuff[0];

    if (ps_stm401->qw_irq_status) {
        irq_status |= ps_stm401->qw_irq_status;
        ps_stm401->qw_irq_status = 0;
    }

    /* First, check for error messages */
    if (irq_status & M_LOG_MSG) {
        stm401_cmdbuff[0] = ERROR_STATUS;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff,
                                    1, ESR_SIZE);
        if (err >= 0) {
            memcpy(stat_string, stm401_readbuff, ESR_SIZE);
            stat_string[ESR_SIZE] = 0;
            dev_err(&ps_stm401->client->dev,
                    "STM401 Error: %s\n", stat_string);
        } else
            dev_err(&ps_stm401->client->dev,
                    "Failed to read error message %d\n", err);
    }

    /* Second, check for a reset request */
    if (irq_status & M_HUB_RESET) {
        unsigned char status;

        if (strnstr(stat_string, "modality", ESR_SIZE))
            status = 0x01;
        else if (strnstr(stat_string, "Algo", ESR_SIZE))
            status = 0x02;
        else if (strnstr(stat_string, "Watchdog", ESR_SIZE))
            status = 0x03;
        else
            status = 0x04;

        stm401_as_data_buffer_write(ps_stm401, DT_RESET, &status, 1, 0);

        stm401_reset_and_init();
        dev_err(&ps_stm401->client->dev, "STM401 requested a reset\n");
        goto EXIT;
    }

    /* Check all other status bits */
    if (irq_status & M_DOCK) {
        int state;

        dev_err(&ps_stm401->client->dev,
                "Invalid M_DOCK bit set. irq_status = 0x%06x\n",
                irq_status);

        stm401_cmdbuff[0] = DOCK_DATA;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading Dock state failed\n");
            goto EXIT;
        }
        stm401_as_data_buffer_write(ps_stm401, DT_DOCK,
                                    stm401_readbuff, 1, 0);
        state = stm401_readbuff[DOCK_STATE];
        if (ps_stm401->dsdev.dev != NULL)
            switch_set_state(&ps_stm401->dsdev, state);
        if (ps_stm401->edsdev.dev != NULL)
            switch_set_state(&ps_stm401->edsdev, state);

        dev_dbg(&ps_stm401->client->dev, "Dock status:%d\n", state);
    }
    if (irq_status & M_PROXIMITY) {
        stm401_cmdbuff[0] = PROXIMITY;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading prox from stm401 failed\n");
            goto EXIT;
        }
        stm401_as_data_buffer_write(ps_stm401, DT_PROX,
                                    stm401_readbuff, 1, 0);

        dev_dbg(&ps_stm401->client->dev,
                "Sending Proximity distance %d\n",
                stm401_readbuff[PROX_DISTANCE]);
    }
    if (irq_status & M_TOUCH) {
        if (stm401_display_handle_touch_locked(ps_stm401) < 0)
            goto EXIT;
    }
    if (irq_status & M_COVER) {
        int state;
        stm401_cmdbuff[0] = COVER_DATA;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading Cover state failed\n");
            goto EXIT;
        }

        state = stm401_readbuff[COVER_STATE];
        if (state > 0)
            state = 1;

        input_report_switch(ps_stm401->input_dev, SW_LID, state);
        input_sync(ps_stm401->input_dev);

        dev_dbg(&ps_stm401->client->dev, "Cover status: %d\n", state);
    }
    if (irq_status & M_QUICKPEEK) {
        if (stm401_display_handle_quickpeek_locked(ps_stm401,
                irq_status == M_QUICKPEEK) < 0)
            goto EXIT;
    }
    if (irq_status & M_FLATUP) {
        stm401_cmdbuff[0] = FLAT_DATA;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading flat data from stm401 failed\n");
            goto EXIT;
        }
        stm401_as_data_buffer_write(ps_stm401, DT_FLAT_UP,
                                    stm401_readbuff, 1, 0);

        dev_dbg(&ps_stm401->client->dev, "Sending Flat up %d\n",
                stm401_readbuff[FLAT_UP]);
    }
    if (irq_status & M_FLATDOWN) {
        stm401_cmdbuff[0] = FLAT_DATA;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading flat data from stm401 failed\n");
            goto EXIT;
        }
        stm401_as_data_buffer_write(ps_stm401, DT_FLAT_DOWN,
                                    stm401_readbuff, 1, 0);

        dev_dbg(&ps_stm401->client->dev, "Sending Flat down %d\n",
                stm401_readbuff[FLAT_DOWN]);
    }
    if (irq_status & M_STOWED) {
        stm401_cmdbuff[0] = STOWED;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading stowed from stm401 failed\n");
            goto EXIT;
        }
        stm401_as_data_buffer_write(ps_stm401, DT_STOWED,
                                    stm401_readbuff, 1, 0);

        dev_dbg(&ps_stm401->client->dev,
                "Sending Stowed status %d\n", stm401_readbuff[STOWED]);
    }
    if (irq_status & M_CAMERA_ACT) {
        stm401_cmdbuff[0] = CAMERA;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading camera data from stm failed\n");
            goto EXIT;
        }
        stm401_as_data_buffer_write(ps_stm401, DT_CAMERA_ACT,
                                    stm401_readbuff, 2, 0);

        dev_dbg(&ps_stm401->client->dev,
                "Sending Camera: %d\n", STM16_TO_HOST(CAMERA_VALUE));

        input_report_key(ps_stm401->input_dev, KEY_CAMERA, 1);
        input_report_key(ps_stm401->input_dev, KEY_CAMERA, 0);
        input_sync(ps_stm401->input_dev);
        dev_dbg(&ps_stm401->client->dev,
                "Report camkey toggle\n");
    }
    if (irq_status & M_NFC) {
        stm401_cmdbuff[0] = NFC;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading nfc data from stm failed\n");
            goto EXIT;
        }
        stm401_as_data_buffer_write(ps_stm401, DT_NFC,
                                    stm401_readbuff, 1, 0);

        dev_dbg(&ps_stm401->client->dev,
                "Sending NFC value: %d\n", stm401_readbuff[NFC_VALUE]);

    }
    if (irq_status & M_SIM) {
        stm401_cmdbuff[0] = SIM;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading sig_motion data from stm failed\n");
            goto EXIT;
        }
        stm401_as_data_buffer_write(ps_stm401, DT_SIM,
                                    stm401_readbuff, 2, 0);

        /* This is one shot sensor */
        stm401_g_wake_sensor_state &= (~M_SIM);

        dev_dbg(&ps_stm401->client->dev, "Sending SIM Value=%d\n",
                STM16_TO_HOST(SIM_DATA));
    }
    if (irq_status & M_CHOPCHOP) {
        stm401_cmdbuff[0] = CHOPCHOP;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading chopchop data from stm failed\n");
            goto EXIT;
        }

        stm401_as_data_buffer_write(ps_stm401, DT_CHOPCHOP,
                                    stm401_readbuff, 2, 0);

        dev_dbg(&ps_stm401->client->dev, "ChopChop triggered. Gyro aborts=%d\n",
                STM16_TO_HOST(CHOPCHOP_DATA));
    }
    if (irq2_status & M_MMOVEME) {
        unsigned char status;
        /* Client recieving action will be upper 2 most significant */
        /* bits of the least significant byte of status. */
        status = (irq2_status & STM401_CLIENT_MASK) | M_MMOVEME;
        stm401_ms_data_buffer_write(ps_stm401, DT_MMMOVE, &status, 1);

        dev_dbg(&ps_stm401->client->dev,
                "Sending meaningful movement event\n");
    }
    if (irq2_status & M_NOMMOVE) {
        unsigned char status;
        /* Client recieving action will be upper 2 most significant */
        /* bits of the least significant byte of status. */
        status = (irq2_status & STM401_CLIENT_MASK) | M_NOMMOVE;
        stm401_ms_data_buffer_write(ps_stm401, DT_NOMOVE, &status, 1);

        dev_dbg(&ps_stm401->client->dev,
                "Sending no meaningful movement event\n");
    }
    if (irq2_status & M_ALGO_MODALITY) {
        stm401_cmdbuff[0] =
            stm401_algo_info[STM401_IDX_MODALITY].evt_register;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1,
                                    STM401_EVT_SZ_TRANSITION);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading modality event failed\n");
            goto EXIT;
        }
        stm401_readbuff[ALGO_TYPE] = STM401_IDX_MODALITY;
        stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT,
                                    stm401_readbuff, 8);
        dev_dbg(&ps_stm401->client->dev, "Sending modality event\n");
    }
    if (irq2_status & M_ALGO_ORIENTATION) {
        stm401_cmdbuff[0] =
            stm401_algo_info[STM401_IDX_ORIENTATION].evt_register;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1,
                                    STM401_EVT_SZ_TRANSITION);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading orientation event failed\n");
            goto EXIT;
        }
        stm401_readbuff[ALGO_TYPE] = STM401_IDX_ORIENTATION;
        stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT,
                                    stm401_readbuff, 8);
        dev_dbg(&ps_stm401->client->dev, "Sending orientation event\n");
    }
    if (irq2_status & M_ALGO_STOWED) {
        stm401_cmdbuff[0] =
            stm401_algo_info[STM401_IDX_STOWED].evt_register;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1,
                                    STM401_EVT_SZ_TRANSITION);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading stowed event failed\n");
            goto EXIT;
        }
        stm401_readbuff[ALGO_TYPE] = STM401_IDX_STOWED;
        stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT,
                                    stm401_readbuff, 8);
        dev_dbg(&ps_stm401->client->dev, "Sending stowed event\n");
    }
    if (irq2_status & M_ALGO_ACCUM_MODALITY) {
        stm401_cmdbuff[0] =
            stm401_algo_info[STM401_IDX_ACCUM_MODALITY]
            .evt_register;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1,
                                    STM401_EVT_SZ_ACCUM_STATE);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading accum modality event failed\n");
            goto EXIT;
        }
        stm401_readbuff[ALGO_TYPE] = STM401_IDX_ACCUM_MODALITY;
        stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT,
                                    stm401_readbuff, 8);
        dev_dbg(&ps_stm401->client->dev, "Sending accum modality event\n");
    }
    if (irq2_status & M_ALGO_ACCUM_MVMT) {
        stm401_cmdbuff[0] =
            stm401_algo_info[STM401_IDX_ACCUM_MVMT].evt_register;
        err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1,
                                    STM401_EVT_SZ_ACCUM_MVMT);
        if (err < 0) {
            dev_err(&ps_stm401->client->dev,
                    "Reading accum mvmt event failed\n");
            goto EXIT;
        }
        stm401_readbuff[ALGO_TYPE] = STM401_IDX_ACCUM_MVMT;
        stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT,
                                    stm401_readbuff, 8);
        dev_dbg(&ps_stm401->client->dev, "Sending accum mvmt event\n");
    }
    if (irq2_status & M_IR_WAKE_GESTURE) {
        err = stm401_process_ir_gesture(ps_stm401);
        if (err < 0)
            goto EXIT;
    }
    if (irq3_status & M_GENERIC_INTRPT) {

        dev_err(&ps_stm401->client->dev,
                "Invalid M_GENERIC_INTRPT bit set. irq_status = 0x%06x\n",
                irq_status);

        /* x (data1) : irq3_status */
        stm401_ms_data_buffer_write(ps_stm401, DT_GENERIC_INT,
                                    &irq3_status, 1);
        dev_dbg(&ps_stm401->client->dev,
                "Sending generic interrupt event:%d\n", irq3_status);
    }

EXIT:
    stm401_sleep(ps_stm401);
EXIT_NO_WAKE:
    mutex_unlock(&ps_stm401->lock);
}
Example #19
0
static void
whois(const char *query, const char *hostname, int flags)
{
	FILE *sfi, *sfo;
	struct addrinfo *hostres, *res;
	char *buf, *host, *nhost, *p;
	int i, s;
	size_t c, len;

	hostres = gethostinfo(hostname, 1);
	for (res = hostres; res; res = res->ai_next) {
		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
		if (s < 0)
			continue;
		if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
			break;
		close(s);
	}
	freeaddrinfo(hostres);
	if (res == NULL)
		err(EX_OSERR, "connect()");

	sfi = fdopen(s, "r");
	sfo = fdopen(s, "w");
	if (sfi == NULL || sfo == NULL)
		err(EX_OSERR, "fdopen()");
	if (strcmp(hostname, GERMNICHOST) == 0) {
#ifdef __APPLE__
		/* radar:18958875 radar:21503897 */
		fprintf(sfo, "-T dn -C UTF-8 %s\r\n", query);
#else
		fprintf(sfo, "-T dn,ace -C US-ASCII %s\r\n", query);
#endif
	} else {
		fprintf(sfo, "%s\r\n", query);
	}
	fflush(sfo);
	nhost = NULL;
	while ((buf = fgetln(sfi, &len)) != NULL) {
		while (len > 0 && isspace((unsigned char)buf[len - 1]))
			buf[--len] = '\0';
		printf("%.*s\n", (int)len, buf);

		if ((flags & WHOIS_RECURSE) && nhost == NULL) {
			host = strnstr(buf, WHOIS_SERVER_ID, len);
			if (host != NULL) {
				host += sizeof(WHOIS_SERVER_ID) - 1;
				for (p = host; p < buf + len; p++) {
					if (!ishost(*p)) {
						*p = '\0';
						break;
					}
				}
				s_asprintf(&nhost, "%.*s",
				     (int)(buf + len - host), host);
			} else if ((host =
			    strnstr(buf, WHOIS_ORG_SERVER_ID, len)) != NULL) {
				host += sizeof(WHOIS_ORG_SERVER_ID) - 1;
				for (p = host; p < buf + len; p++) {
					if (!ishost(*p)) {
						*p = '\0';
						break;
					}
				}
				s_asprintf(&nhost, "%.*s",
				    (int)(buf + len - host), host);
			} else if (strcmp(hostname, ANICHOST) == 0) {
				for (c = 0; c <= len; c++)
					buf[c] = tolower((int)buf[c]);
				for (i = 0; ip_whois[i] != NULL; i++) {
					if (strnstr(buf, ip_whois[i], len) !=
					    NULL) {
						s_asprintf(&nhost, "%s",
						    ip_whois[i]);
						break;
					}
				}
			}
		}
	}
	if (nhost != NULL) {
		whois(query, nhost, 0);
		free(nhost);
	}
}
Example #20
0
/*
 * Check if the host name h passed matches the pattern passed in m which
 * is usually part of subjectAltName or CN of a certificate presented to
 * the client. This includes wildcard matching. The algorithm is based on
 * RFC6125, sections 6.4.3 and 7.2, which clarifies RFC2818 and RFC3280.
 */
static int
fetch_ssl_hname_match(const char *h, size_t hlen, const char *m,
    size_t mlen)
{
	int delta, hdotidx, mdot1idx, wcidx;
	const char *hdot, *mdot1, *mdot2;
	const char *wc; /* wildcard */

	if (!(h && *h && m && *m))
		return (0);
	if ((wc = strnstr(m, "*", mlen)) == NULL)
		return (fetch_ssl_hname_equal(h, hlen, m, mlen));
	wcidx = wc - m;
	/* hostname should not be just dots and numbers */
	if (fetch_ssl_hname_is_only_numbers(h, hlen))
		return (0);
	/* only one wildcard allowed in pattern */
	if (strnstr(wc + 1, "*", mlen - wcidx - 1) != NULL)
		return (0);
	/*
	 * there must be at least two more domain labels and
	 * wildcard has to be in the leftmost label (RFC6125)
	 */
	mdot1 = strnstr(m, ".", mlen);
	if (mdot1 == NULL || mdot1 < wc || (mlen - (mdot1 - m)) < 4)
		return (0);
	mdot1idx = mdot1 - m;
	mdot2 = strnstr(mdot1 + 1, ".", mlen - mdot1idx - 1);
	if (mdot2 == NULL || (mlen - (mdot2 - m)) < 2)
		return (0);
	/* hostname must contain a dot and not be the 1st char */
	hdot = strnstr(h, ".", hlen);
	if (hdot == NULL || hdot == h)
		return (0);
	hdotidx = hdot - h;
	/*
	 * host part of hostname must be at least as long as
	 * pattern it's supposed to match
	 */
	if (hdotidx < mdot1idx)
		return (0);
	/*
	 * don't allow wildcards in non-traditional domain names
	 * (IDN, A-label, U-label...)
	 */
	if (!fetch_ssl_is_trad_domain_label(h, hdotidx, 0) ||
	    !fetch_ssl_is_trad_domain_label(m, mdot1idx, 1))
		return (0);
	/* match domain part (part after first dot) */
	if (!fetch_ssl_hname_equal(hdot, hlen - hdotidx, mdot1,
	    mlen - mdot1idx))
		return (0);
	/* match part left of wildcard */
	if (!fetch_ssl_hname_equal(h, wcidx, m, wcidx))
		return (0);
	/* match part right of wildcard */
	delta = mdot1idx - wcidx - 1;
	if (!fetch_ssl_hname_equal(hdot - delta, delta,
	    mdot1 - delta, delta))
		return (0);
	/* all tests succeded, it's a match */
	return (1);
}
Example #21
0
Network::Err Network::handleConnection(SocketData* conn)
{
	int connSock = conn->fd;
	char* buffer = conn->readBuf;
	size_t toRead = readBufSize - conn->readLen;
	ssize_t receivedBytes = recv(connSock, buffer + conn->readLen, toRead, 0);
	if (receivedBytes == -1)
	{
		Log::err("recv(): %s", strerror(errno));
		if (close(connSock) == -1)
		{
			Log::err("close(): %s", strerror(errno));
		}
		return Err::Process;
	}
	else if (receivedBytes == 0)
	{
		Log::info("Closing disconnected socket");
		if (close(connSock) == -1)
		{
			Log::err("close(): %s", strerror(errno));
		}
		return Err::Process;
	}
	
	conn->readLen += receivedBytes;
	receivedBytes = conn->readLen;
	
	if (strnstr(buffer, "\r\n\r\n", receivedBytes) == nullptr
		&& strnstr(buffer, "\r\r", receivedBytes) == nullptr
		&& strnstr(buffer, "\n\n", receivedBytes) == nullptr)
	{
		if (receivedBytes == readBufSize)
		{
			if (close(connSock) == -1)
			{
				Log::err("close(): %s", strerror(errno));
			}
			return Err::Process;
		}
		
		return Err::ReadMore;
	}
	
	char* rPos = (char*)memchr(buffer, '\r', receivedBytes);
	char* nPos = (char*)memchr(buffer, '\n', receivedBytes);
	
	char* lineEndPos = nPos;
	if (nPos == nullptr || (rPos != nullptr && rPos < nPos))
	{
		lineEndPos = rPos;
	}
	
	RequestResult res;
	RequestErr status;
	size_t requestLineLen;
	if (lineEndPos == nullptr)
	{
		requestLineLen = receivedBytes;
		status = RequestErr::BAD_REQUEST;
		res.version = HttpVersion::V1_0;
	}
	else
	{
		requestLineLen = lineEndPos - buffer;
		status = readRequestLine(buffer, requestLineLen, res);
	}
	
	char pathBuff[1024];
	const char* path = nullptr;
	
	switch (status)
	{
	case RequestErr::OK:
		{
			int unescapedLen = unescape(res.path, pathBuff, res.pathLen);
			if (unescapedLen == -1)
			{
				status = RequestErr::BAD_REQUEST;
				path = "/400.html";
			}
			else
			{						
				pathBuff[unescapedLen] = 0;
				path = pathBuff;
			}
		}
		break;
		
	case RequestErr::BAD_REQUEST:
		path = "/400.html";
		break;
		
	case RequestErr::FORBIDDEN:
		path = "/403.html";
		break;
		
	case RequestErr::NOT_FOUND:
		path = "/404.html";
		break;
		
	case RequestErr::INTERNAL:
		path = "/500.html";
		break;
		
	case RequestErr::NOT_IMPLEMENTED:
		path = "/501.html";
		break;
	}
	
	if (strcmp(path, "/") == 0)
	{
		path = "/index.html";
	}
	
	int file = open(path, O_RDONLY);
	if (file == -1)
	{
		status = RequestErr::NOT_FOUND;
		file = open("/404.html", O_RDONLY);
		
		if (file == -1)
		{
			Log::err("open(): %s, Failed to open 404.html", strerror(errno));
			
			if (close(connSock) == -1)
			{
				Log::err("close(): %s", strerror(errno));
			}
			return Err::Process;
		}
	}
		
	struct stat fileStat;
	if (fstat(file, &fileStat) == -1)
	{
		Log::err("fstat(): %s", strerror(errno));
		
		if (close(file) == -1)
		{
			Log::err("close(): %s", strerror(errno));
		}
		
		if (close(connSock) == -1)
		{
			Log::err("close(): %s", strerror(errno));
		}
		
		return Err::Process;
	}
	
	if (res.version >= HttpVersion::V1_0)
	{
		char headerBuff[1024];
		int headerLen = snprintf(headerBuff, sizeof(headerBuff), "HTTP/1.0 %3.3d %s\r\n", (int)status, getStatusStr(status));
		
		const char* mimeType = mimeFinder->findMimeType(dup(file), path);
		if (lseek(file, 0, SEEK_SET) == -1)
		{
			Log::err("lseek(): %s", strerror(errno));
			
			if (close(file) == -1)
			{
				Log::err("close(): %s", strerror(errno));
			}
			
			if (close(connSock) == -1)
			{
				Log::err("close(): %s", strerror(errno));
			}
			
			return Err::Process;
		}
		if (mimeType != nullptr)
		{
			headerLen += snprintf(headerBuff + headerLen, sizeof(headerBuff) - headerLen,
				"Content-Type: %s\r\n", mimeType);
		}
		
		headerLen += snprintf(headerBuff + headerLen, sizeof(headerBuff) - headerLen, "Content-Length: %ld\r\n\r\n", fileStat.st_size);
		
		if (send(connSock, headerBuff, headerLen, 0) == -1)
		{
			Log::err("send(): %s", strerror(errno));
			
			if (close(file) == -1)
			{
				Log::err("close(): %s", strerror(errno));
			}
			
			if (close(connSock) == -1)
			{
				Log::err("close(): %s", strerror(errno));
			}
			
			return Err::Process;
		}
	}
	
	size_t bytesSent;
	if(res.method == HttpMethod::GET)
	{
		if ((bytesSent = sendfile(connSock, file, nullptr, fileStat.st_size)) == -1)
		{
			Log::err("sendfile(): %s", strerror(errno));
			
			if (close(file) == -1)
			{
				Log::err("close(): %s", strerror(errno));
			}
			
			if (close(connSock) == -1)
			{
				Log::err("close(): %s", strerror(errno));
			}
			
			return Err::Process;
		}
	}
	
	if(close(file) == -1)
	{
		Log::err("close(): %s", strerror(errno));
	}
	
	logStatus(buffer, requestLineLen, connSock, bytesSent, (int)status);
	
	if (close(connSock) == -1)
	{
		Log::err("close(): %s", strerror(errno));
	}
	
	return Err::OK;
}
void LogKlog::sniffTime(log_time &now,
                        const char **buf, size_t len,
                        bool reverse) {
    const char *cp = now.strptime(*buf, "[ %s.%q]");
    if (cp && (cp >= &(*buf)[len])) {
        cp = NULL;
    }
    len -= cp - *buf;
    if (cp) {
        static const char healthd[] = "healthd";
        static const char battery[] = ": battery ";

        if (len && isspace(*cp)) {
            ++cp;
            --len;
        }
        *buf = cp;

        const char *b;
        if (((b = strnstr(cp, len, suspendStr)))
                && ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) {
            len -= b - cp;
            calculateCorrection(now, b, len);
        } else if (((b = strnstr(cp, len, resumeStr)))
                && ((size_t)((b += sizeof(resumeStr) - 1) - cp) < len)) {
            len -= b - cp;
            calculateCorrection(now, b, len);
        } else if (((b = strnstr(cp, len, healthd)))
                && ((size_t)((b += sizeof(healthd) - 1) - cp) < len)
                && ((b = strnstr(b, len -= b - cp, battery)))
                && ((size_t)((b += sizeof(battery) - 1) - cp) < len)) {
            len -= b - cp;
            // NB: healthd is roughly 150us late, worth the price to deal with
            //     ntp-induced or hardware clock drift.
            // look for " 2???-??-?? ??:??:??.????????? ???"
            for (; len && *b && (*b != '\n'); ++b, --len) {
                if ((b[0] == ' ') && (b[1] == '2') && (b[5] == '-')) {
                    calculateCorrection(now, b + 1, len - 1);
                    break;
                }
            }
        } else if (((b = strnstr(cp, len, suspendedStr)))
                && ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) {
            len -= b - cp;
            log_time real;
            char *endp;
            real.tv_sec = strtol(b, &endp, 10);
            if ((*endp == '.') && ((size_t)(endp - b) < len)) {
                unsigned long multiplier = NS_PER_SEC;
                real.tv_nsec = 0;
                len -= endp - b;
                while (--len && isdigit(*++endp) && (multiplier /= 10)) {
                    real.tv_nsec += (*endp - '0') * multiplier;
                }
                if (reverse) {
                    correction -= real;
                } else {
                    correction += real;
                }
            }
        }

        convertMonotonicToReal(now);
    } else {
        now = log_time(CLOCK_REALTIME);
    }
}
Example #23
0
int do_sip_reply_invite(pvp_uthttp put, char **ut_buf, u32 *pack_len)
{
    const static char FLG_INIP4[] = "IN IP4 ";
    const static char FLG_VPORT[] = "m=video ";
    char cli_ip[16] = {0}; // outer server ip
    char   *pstr = NULL;
    char   sport[8] = {0};    /*Source port*/
    char r_src[64] = {0};
    char r_dst[64] = {0};
    char lip[16] = {0};
    char dip[16] = {0};
    char *ptr = NULL;
    u16 nlport = 0;
    char call_id[128] = {0};

    puts("******** 1");
    if ((pstr = strstr(*ut_buf, FLG_VPORT)) != NULL)
    {
    puts("******** 2");
    puts(*ut_buf);
        pstr += sizeof(FLG_VPORT)-1;
        sscanf(pstr, "%[0-9]", sport);
        if ((nlport = pplist_getidle_port_x()) == 0)
        {
            logwar_out("get idle port failed!");
            return -1;
        }

    puts("******** 3");
        // replace ip
        if ((ptr = strnstr(*ut_buf, FLG_INIP4, *pack_len, true)) != NULL)
        {
            ptr += sizeof(FLG_INIP4)-1;
            sscanf(ptr, "%[0-9.]", dip);
            inet_ultoa(__gg.outer_addr, lip);
            sprintf(r_src, "%s%s", FLG_INIP4, dip);
            //sprintf(r_dst, "%s%s", FLG_INIP4, g_value[L_AUTHIP]);
            sprintf(r_dst, "%s%s", FLG_INIP4, lip);
            strreplace_pos(NULL, NULL, ut_buf, r_src, r_dst, -1, pack_len);
        }
    puts("******** 4");
        // replace port
        sprintf(r_src, "%s%s", FLG_VPORT, sport);
        sprintf(r_dst, "%s%d", FLG_VPORT, nlport);
        strreplace_pos(NULL,NULL, ut_buf, r_src, r_dst, 1, pack_len);
        
        inet_ultoa(put->src_ip, cli_ip);

        // replace invite ip
        replace_cmd_ip_port(ut_buf, pack_len, cli_ip, put->src_port);

    puts("******** 5");
        // start proxy
        char camera_id[32] = {0};
        int ret = -1;
        clivlist *pcvn = NULL;
        if (oss_malloc(&pcvn, sizeof(clivlist)) < 0)
            return -1;
        get_virtual_cameraid(camera_id);

        strcpy(pcvn->visit_user, cli_ip);
        strcpy(pcvn->camera_id, camera_id);
        //if (is_tms())
            //pcvn->lip = __gg.inner_addr;
        //else
            pcvn->lip = __gg.outer_addr;
        pcvn->dip = inet_atoul(dip);
        pcvn->lvport = nlport;
        pcvn->dvport = atoi(sport);
        pcvn->platform_id = a_get_pmid();
        // pcvn->vstream_tout = put->session_tout;   //
        // 信令超时时间需要很长,如果视频流使用相同超时时间,会有大量已经使用完的视频进程逗留在系统中
        pcvn->vstream_tout = 60;
        pcvn->bind_video_port = nlport;

    puts("******** 6");
        if (get_call_id(*ut_buf, *pack_len, call_id, sizeof(call_id)) == NULL)
            logdbg_out("获取Call id 失败!");
        else if ( ! gl_set_data(call_id, (char*)&nlport, sizeof(nlport)))
            logdbg_out("记录Call id 失败!");
    
        ret = __start_vs_udp_proxy(pcvn, true, __gg.ferry_port + 1);
        oss_free(&pcvn);

        //sip_replace_contact(ut_buf, pack_len, g_value[L_AUTHIP], 5060);
        //do_sip_reply_replace_by_key(put, SIP_FLAG_CONTACT, ut_buf, pack_len);
    }

    return 1;
}
//
// log a message into the kernel log buffer
//
// Filter rules to parse <PRI> <TIME> <tag> and <message> in order for
// them to appear correct in the logcat output:
//
// LOG_KERN (0):
// <PRI>[<TIME>] <tag> ":" <message>
// <PRI>[<TIME>] <tag> <tag> ":" <message>
// <PRI>[<TIME>] <tag> <tag>_work ":" <message>
// <PRI>[<TIME>] <tag> '<tag>.<num>' ":" <message>
// <PRI>[<TIME>] <tag> '<tag><num>' ":" <message>
// <PRI>[<TIME>] <tag>_host '<tag>.<num>' ":" <message>
// (unimplemented) <PRI>[<TIME>] <tag> '<num>.<tag>' ":" <message>
// <PRI>[<TIME>] "[INFO]"<tag> : <message>
// <PRI>[<TIME>] "------------[ cut here ]------------"   (?)
// <PRI>[<TIME>] "---[ end trace 3225a3070ca3e4ac ]---"   (?)
// LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
// LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_FTP:
// <PRI+TAG>[<TIME>] (see sys/syslog.h)
// Observe:
//  Minimum tag length = 3   NB: drops things like r5:c00bbadf, but allow PM:
//  Maximum tag words = 2
//  Maximum tag length = 16  NB: we are thinking of how ugly logcat can get.
//  Not a Tag if there is no message content.
//  leading additional spaces means no tag, inherit last tag.
//  Not a Tag if <tag>: is "ERROR:", "WARNING:", "INFO:" or "CPU:"
// Drop:
//  empty messages
//  messages with ' audit(' in them if auditd is running
//  logd.klogd:
// return -1 if message logd.klogd: <signature>
//
int LogKlog::log(const char *buf, size_t len) {
    if (auditd && strnstr(buf, len, " audit(")) {
        return 0;
    }

    const char *p = buf;
    int pri = parseKernelPrio(&p, len);

    log_time now;
    sniffTime(now, &p, len - (p - buf), false);

    // sniff for start marker
    const char klogd_message[] = "logd.klogd: ";
    const char *start = strnstr(p, len - (p - buf), klogd_message);
    if (start) {
        uint64_t sig = strtoll(start + sizeof(klogd_message) - 1, NULL, 10);
        if (sig == signature.nsec()) {
            if (initialized) {
                enableLogging = true;
            } else {
                enableLogging = false;
            }
            return -1;
        }
        return 0;
    }

    if (!enableLogging) {
        return 0;
    }

    // Parse pid, tid and uid
    const pid_t pid = sniffPid(p, len - (p - buf));
    const pid_t tid = pid;
    const uid_t uid = pid ? logbuf->pidToUid(pid) : 0;

    // Parse (rules at top) to pull out a tag from the incoming kernel message.
    // Some may view the following as an ugly heuristic, the desire is to
    // beautify the kernel logs into an Android Logging format; the goal is
    // admirable but costly.
    while ((isspace(*p) || !*p) && (p < &buf[len])) {
        ++p;
    }
    if (p >= &buf[len]) { // timestamp, no content
        return 0;
    }
    start = p;
    const char *tag = "";
    const char *etag = tag;
    size_t taglen = len - (p - buf);
    if (!isspace(*p) && *p) {
        const char *bt, *et, *cp;

        bt = p;
        if (!strncmp(p, "[INFO]", 6)) {
            // <PRI>[<TIME>] "[INFO]"<tag> ":" message
            bt = p + 6;
            taglen -= 6;
        }
        for(et = bt; taglen && *et && (*et != ':') && !isspace(*et); ++et, --taglen) {
           // skip ':' within [ ... ]
           if (*et == '[') {
               while (taglen && *et && *et != ']') {
                   ++et;
                   --taglen;
               }
            }
        }
        for(cp = et; taglen && isspace(*cp); ++cp, --taglen);
        size_t size;

        if (*cp == ':') {
            // One Word
            tag = bt;
            etag = et;
            p = cp + 1;
        } else if (taglen) {
            size = et - bt;
            if (strncmp(bt, cp, size)) {
                // <PRI>[<TIME>] <tag>_host '<tag>.<num>' : message
                if (!strncmp(bt + size - 5, "_host", 5)
                        && !strncmp(bt, cp, size - 5)) {
                    const char *b = cp;
                    cp += size - 5;
                    taglen -= size - 5;
                    if (*cp == '.') {
                        while (--taglen && !isspace(*++cp) && (*cp != ':'));
                        const char *e;
                        for(e = cp; taglen && isspace(*cp); ++cp, --taglen);
                        if (*cp == ':') {
                            tag = b;
                            etag = e;
                            p = cp + 1;
                        }
                    }
                } else {
                    while (--taglen && !isspace(*++cp) && (*cp != ':'));
                    const char *e;
                    for(e = cp; taglen && isspace(*cp); ++cp, --taglen);
                    // Two words
                    if (*cp == ':') {
                        tag = bt;
                        etag = e;
                        p = cp + 1;
                    }
                }
            } else if (isspace(cp[size])) {
                cp += size;
                taglen -= size;
                while (--taglen && isspace(*++cp));
                // <PRI>[<TIME>] <tag> <tag> : message
                if (*cp == ':') {
                    tag = bt;
                    etag = et;
                    p = cp + 1;
                }
            } else if (cp[size] == ':') {
                // <PRI>[<TIME>] <tag> <tag> : message
                tag = bt;
                etag = et;
                p = cp + size + 1;
            } else if ((cp[size] == '.') || isdigit(cp[size])) {
                // <PRI>[<TIME>] <tag> '<tag>.<num>' : message
                // <PRI>[<TIME>] <tag> '<tag><num>' : message
                const char *b = cp;
                cp += size;
                taglen -= size;
                while (--taglen && !isspace(*++cp) && (*cp != ':'));
                const char *e = cp;
                while (taglen && isspace(*cp)) {
                    ++cp;
                    --taglen;
                }
                if (*cp == ':') {
                    tag = b;
                    etag = e;
                    p = cp + 1;
                }
            } else {
                while (--taglen && !isspace(*++cp) && (*cp != ':'));
                const char *e = cp;
                while (taglen && isspace(*cp)) {
                    ++cp;
                    --taglen;
                }
                // Two words
                if (*cp == ':') {
                    tag = bt;
                    etag = e;
                    p = cp + 1;
                }
            }
        }
        size = etag - tag;
        if ((size <= 1)
            // register names like x9
                || ((size == 2) && (isdigit(tag[0]) || isdigit(tag[1])))
            // register names like x18 but not driver names like en0
                || ((size == 3) && (isdigit(tag[1]) && isdigit(tag[2])))
            // blacklist
                || ((size == 3) && !strncmp(tag, "CPU", 3))
                || ((size == 7) && !strncasecmp(tag, "WARNING", 7))
                || ((size == 5) && !strncasecmp(tag, "ERROR", 5))
                || ((size == 4) && !strncasecmp(tag, "INFO", 4))) {
            p = start;
            etag = tag = "";
        }
    }
    // Suppress additional stutter in tag:
    //   eg: [143:healthd]healthd -> [143:healthd]
    taglen = etag - tag;
    // Mediatek-special printk induced stutter
    const char *mp = strnrchr(tag, ']', taglen);
    if (mp && (++mp < etag)) {
        size_t s = etag - mp;
        if (((s + s) < taglen) && !memcmp(mp, mp - 1 - s, s)) {
            taglen = mp - tag;
        }
    }
    // skip leading space
    while ((isspace(*p) || !*p) && (p < &buf[len])) {
        ++p;
    }
    // truncate trailing space or nuls
    size_t b = len - (p - buf);
    while (b && (isspace(p[b-1]) || !p[b-1])) {
        --b;
    }
    // trick ... allow tag with empty content to be logged. log() drops empty
    if (!b && taglen) {
        p = " ";
        b = 1;
    }
    size_t n = 1 + taglen + 1 + b + 1;
    int rc = n;
    if ((taglen > n) || (b > n)) { // Can not happen ...
        rc = -EINVAL;
        return rc;
    }

    // Allocate a buffer to hold the interpreted log message
    char *newstr = reinterpret_cast<char *>(malloc(n));
    if (!newstr) {
        rc = -ENOMEM;
        return rc;
    }
    char *np = newstr;

    // Convert priority into single-byte Android logger priority
    *np = convertKernelPrioToAndroidPrio(pri);
    ++np;

    // Copy parsed tag following priority
    memcpy(np, tag, taglen);
    np += taglen;
    *np = '\0';
    ++np;

    // Copy main message to the remainder
    memcpy(np, p, b);
    np[b] = '\0';

    // Log message
    rc = logbuf->log(LOG_ID_KERNEL, now, uid, pid, tid, newstr,
                     (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX);
    free(newstr);

    // notify readers
    if (!rc) {
        reader->notifyNewLog();
    }

    return rc;
}
Example #25
0
/**
 * mdss_dsi_find_panel_of_node(): find device node of dsi panel
 * @pdev: platform_device of the dsi ctrl node
 * @panel_cfg: string containing intf specific config data
 *
 * Function finds the panel device node using the interface
 * specific configuration data. This configuration data is
 * could be derived from the result of bootloader's GCDB
 * panel detection mechanism. If such config data doesn't
 * exist then this panel returns the default panel configured
 * in the device tree.
 *
 * returns pointer to panel node on success, NULL on error.
 */
static struct device_node *mdss_dsi_find_panel_of_node(
	struct platform_device *pdev, char *panel_cfg,
	struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
	int len, i;
	int ctrl_id = pdev->id - 1;
	char panel_name[MDSS_MAX_PANEL_LEN];
	char ctrl_id_stream[3] =  "0:";
	char *stream = NULL, *pan = NULL;
	struct device_node *dsi_pan_node = NULL, *mdss_node = NULL;

	len = strlen(panel_cfg);
	if (!len) {
		dsi_pan_node = mdss_dsi_panel_search_dt_nodes(pdev,
								ctrl_pdata);
		if (dsi_pan_node)
			return dsi_pan_node;

		/* no panel cfg chg, parse dt */
		pr_debug("%s:%d: no cmd line cfg present\n",
			 __func__, __LINE__);
		goto end;
	} else {
		if (ctrl_id == 1)
			strlcpy(ctrl_id_stream, "1:", 3);

		stream = strnstr(panel_cfg, ctrl_id_stream, len);
		if (!stream) {
			pr_err("controller config is not present\n");
			goto end;
		}
		stream += 2;

		pan = strnchr(stream, strlen(stream), ':');
		if (!pan) {
			strlcpy(panel_name, stream, MDSS_MAX_PANEL_LEN);
		} else {
			for (i = 0; (stream + i) < pan; i++)
				panel_name[i] = *(stream + i);
			panel_name[i] = 0;
		}

		pr_debug("%s:%d:%s:%s\n", __func__, __LINE__,
			 panel_cfg, panel_name);

		mdss_node = of_parse_phandle(pdev->dev.of_node,
					     "qcom,mdss-mdp", 0);

		if (!mdss_node) {
			pr_err("%s: %d: mdss_node null\n",
			       __func__, __LINE__);
			return NULL;
		}
		dsi_pan_node = of_find_node_by_name(mdss_node,
						    panel_name);
		if (!dsi_pan_node) {
			pr_err("%s: invalid pan node, selecting prim panel\n",
			       __func__);
			goto end;
		}
		return dsi_pan_node;
	}
end:
	dsi_pan_node = mdss_dsi_pref_prim_panel(pdev);

	return dsi_pan_node;
}
int WebSocketHandshake::readServerHandshake(const char* header, size_t len)
{
    m_mode = Incomplete;
    if (len < sizeof(webSocketServerHandshakeHeader) - 1) {
        // Just hasn't been received fully yet.
        return -1;
    }
    if (!memcmp(header, webSocketServerHandshakeHeader, sizeof(webSocketServerHandshakeHeader) - 1))
        m_mode = Normal;
    else {
        const String& code = extractResponseCode(header, len);
        if (code.isNull()) {
            m_context->addMessage(ConsoleDestination, JSMessageSource, LogMessageType, ErrorMessageLevel, "Short server handshake: " + String(header, len), 0, clientOrigin());
            return -1;
        }
        if (code.isEmpty()) {
            m_mode = Failed;
            m_context->addMessage(ConsoleDestination, JSMessageSource, LogMessageType, ErrorMessageLevel, "No response code found: " + String(header, len), 0, clientOrigin());
            return len;
        }
        LOG(Network, "response code: %s", code.utf8().data());
        if (code == "401") {
            m_mode = Failed;
            m_context->addMessage(ConsoleDestination, JSMessageSource, LogMessageType, ErrorMessageLevel, "Authentication required, but not implemented yet.", 0, clientOrigin());
            return len;
        } else {
            m_mode = Failed;
            m_context->addMessage(ConsoleDestination, JSMessageSource, LogMessageType, ErrorMessageLevel, "Unexpected response code:" + code, 0, clientOrigin());
            return len;
        }
    }
    const char* p = header + sizeof(webSocketServerHandshakeHeader) - 1;
    const char* end = header + len + 1;

    if (m_mode == Normal) {
        size_t headerSize = end - p;
        if (headerSize < sizeof(webSocketUpgradeHeader) - 1) {
            m_mode = Incomplete;
            return 0;
        }
        if (memcmp(p, webSocketUpgradeHeader, sizeof(webSocketUpgradeHeader) - 1)) {
            m_mode = Failed;
            m_context->addMessage(ConsoleDestination, JSMessageSource, LogMessageType, ErrorMessageLevel, "Bad Upgrade header: " + String(p, end - p), 0, clientOrigin());
            return p - header + sizeof(webSocketUpgradeHeader) - 1;
        }
        p += sizeof(webSocketUpgradeHeader) - 1;

        headerSize = end - p;
        if (headerSize < sizeof(webSocketConnectionHeader) - 1) {
            m_mode = Incomplete;
            return -1;
        }
        if (memcmp(p, webSocketConnectionHeader, sizeof(webSocketConnectionHeader) - 1)) {
            m_mode = Failed;
            m_context->addMessage(ConsoleDestination, JSMessageSource, LogMessageType, ErrorMessageLevel, "Bad Connection header: " + String(p, end - p), 0, clientOrigin());
            return p - header + sizeof(webSocketConnectionHeader) - 1;
        }
        p += sizeof(webSocketConnectionHeader) - 1;
    }

    if (!strnstr(p, "\r\n\r\n", end - p)) {
        // Just hasn't been received fully yet.
        m_mode = Incomplete;
        return -1;
    }
    HTTPHeaderMap headers;
    p = readHTTPHeaders(p, end, &headers);
    if (!p) {
        LOG(Network, "readHTTPHeaders failed");
        m_mode = Failed;
        return len;
    }
    if (!processHeaders(headers)) {
        LOG(Network, "header process failed");
        m_mode = Failed;
        return p - header;
    }
    switch (m_mode) {
    case Normal:
        checkResponseHeaders();
        break;
    default:
        m_mode = Failed;
        break;
    }
    return p - header;
}
Example #27
0
/*****************************************************************************
 * Spawn a new task
 ****************************************************************************/
int SNetThreadingSpawn(snet_entity_t *ent)
/*
  snet_entity_type_t type,
  snet_locvec_t *locvec,
  int location,
  const char *name,
  snet_entityfunc_t func,
  void *arg
  )
 */
{
	int worker;
	snet_entity_descr_t type = SNetEntityDescr(ent);
	int location = SNetEntityNode(ent);
	const char *name = SNetEntityName(ent);
	int l1 = strlen(SNET_SOURCE_PREFIX);
	int l2 = strlen(SNET_SINK_PREFIX);

	if ( type != ENTITY_other) {
		if (sosi_placement && (strnstr(name, SNET_SOURCE_PREFIX, l1) || strnstr(name, SNET_SINK_PREFIX, l2))) {
			worker = LPEL_MAP_SOSI;		// sosi placemnet and entity is source/sink
		} else if (dloc_placement) {
			assert(location != -1);
			worker = location % num_workers;
		} else
			worker = SNetAssignTask( (type==ENTITY_box), name );
	} else
		worker = SNetEntityNode(ent);	//wrapper

	lpel_task_t *t = LpelTaskCreate(
			worker,
			//(lpel_taskfunc_t) func,
			EntityTask,
			ent,
			GetStacksize(type)
	);


#ifdef USE_LOGGING
	if ((mon_flags & SNET_MON_TASK) || (mon_flags & SNET_MON_WAIT_PROP)){
		mon_task_t *mt = SNetThreadingMonTaskCreate(
				LpelTaskGetId(t),
				name
		);
		LpelTaskMonitor(t, mt);
		/* if we monitor the task, we make an entry in the map file */
	}

	if ((mon_flags & SNET_MON_MAP) && mapfile) {
		int tid = LpelTaskGetId(t);
		(void) fprintf(mapfile, "%d%s %d%c", tid, SNetEntityStr(ent), worker, END_LOG_ENTRY);
	}


#endif

	if (type != ENTITY_box && type != ENTITY_fbbuf) {
		LpelTaskSetPriority(t, 1);
	}


	//FIXME only for debugging purposes
	//fflush(mapfile);

	LpelTaskStart(t);
	return 0;
}
Example #28
0
/*
 * Receive a reply message
 */
DBUF *ebxml_receive (NETCON *conn)
{
  long n;
  int e;
  char c, *ch;
  DBUF *b;

  b = dbuf_alloc ();
  n = 0;
  /*
   * read to end of message request header - empty line
   */
  while ((e = net_read (conn, &c, 1)) == 1)
  {
    dbuf_putc (b, c);
    if (c == '\n')
    {
      if (n++ == 1)
        break;
    }
    else if (c != '\r')
      n = 0;
  }
  if (e != 1)
  {
    if (e == 0)
      error ("Acknowledgment header read failed or connection closed\n");
    else
      error ("Timed out reading acknowledgment header\n");
    dbuf_free (b);
    return (NULL);
  }
  ch = strnstr (dbuf_getbuf (b), "Content-Length: ", dbuf_size (b));
  if (ch == NULL)
  {
    error ("Acknowledgment header missing Content-Length\n");
    dbuf_free (b);
    return (NULL);
  }
  n = atol (ch + 16);
  debug ("expecting %d bytes\n", n);

readbytes:

  while (n--)
  {
    if ((e = net_read (conn, &c, 1)) != 1)
    {
      if (e == 0)
        error ("Acknowledgment content read failed or connection closed");
      else
        error ("Timed out reading acknowledgment content\n");
      // note we'll take what we get and hope it's enough...
      break;
    }
    dbuf_putc (b, c);
  }
  if (n = net_available (conn))
  {
    warn ("Found %d unread bytes...\n", n);
    goto readbytes;
  }
  debug ("returning %d bytes\n", dbuf_size (b));
  return (b);
}
Example #29
0
//
// log a message into the kernel log buffer
//
// Filter rules to parse <PRI> <TIME> <tag> and <message> in order for
// them to appear correct in the logcat output:
//
// LOG_KERN (0):
// <PRI>[<TIME>] <tag> ":" <message>
// <PRI>[<TIME>] <tag> <tag> ":" <message>
// <PRI>[<TIME>] <tag> <tag>_work ":" <message>
// <PRI>[<TIME>] <tag> '<tag>.<num>' ":" <message>
// <PRI>[<TIME>] <tag> '<tag><num>' ":" <message>
// <PRI>[<TIME>] <tag>_host '<tag>.<num>' ":" <message>
// (unimplemented) <PRI>[<TIME>] <tag> '<num>.<tag>' ":" <message>
// <PRI>[<TIME>] "[INFO]"<tag> : <message>
// <PRI>[<TIME>] "------------[ cut here ]------------"   (?)
// <PRI>[<TIME>] "---[ end trace 3225a3070ca3e4ac ]---"   (?)
// LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
// LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_FTP:
// <PRI+TAG>[<TIME>] (see sys/syslog.h)
// Observe:
//  Minimum tag length = 3   NB: drops things like r5:c00bbadf, but allow PM:
//  Maximum tag words = 2
//  Maximum tag length = 16  NB: we are thinking of how ugly logcat can get.
//  Not a Tag if there is no message content.
//  leading additional spaces means no tag, inherit last tag.
//  Not a Tag if <tag>: is "ERROR:", "WARNING:", "INFO:" or "CPU:"
// Drop:
//  empty messages
//  messages with ' audit(' in them if auditd is running
//  logd.klogd:
// return -1 if message logd.klogd: <signature>
//
int LogKlog::log(const char *buf, size_t len) {
    if (auditd && strnstr(buf, len, " audit(")) {
        return 0;
    }

    const char *p = buf;
    int pri = parseKernelPrio(&p, len);

    log_time now;
    sniffTime(now, &p, len - (p - buf), false);

    // sniff for start marker
    const char klogd_message[] = "logd.klogd: ";
    const char *start = strnstr(p, len - (p - buf), klogd_message);
    if (start) {
        uint64_t sig = strtoll(start + sizeof(klogd_message) - 1, NULL, 10);
        if (sig == signature.nsec()) {
            if (initialized) {
                enableLogging = true;
            } else {
                enableLogging = false;
            }
            return -1;
        }
        return 0;
    }

    if (!enableLogging) {
        return 0;
    }

    // Parse pid, tid and uid
    const pid_t pid = sniffPid(p, len - (p - buf));
    const pid_t tid = pid;
    const uid_t uid = pid ? logbuf->pidToUid(pid) : 0;

    // Parse (rules at top) to pull out a tag from the incoming kernel message.
    // Some may view the following as an ugly heuristic, the desire is to
    // beautify the kernel logs into an Android Logging format; the goal is
    // admirable but costly.
    while ((p < &buf[len]) && (isspace(*p) || !*p)) {
        ++p;
    }
    if (p >= &buf[len]) { // timestamp, no content
        return 0;
    }
    start = p;
    const char *tag = "";
    const char *etag = tag;
    size_t taglen = len - (p - buf);
    if (!isspace(*p) && *p) {
        const char *bt, *et, *cp;

        bt = p;
        if ((taglen >= 6) && !fast<strncmp>(p, "[INFO]", 6)) {
            // <PRI>[<TIME>] "[INFO]"<tag> ":" message
            bt = p + 6;
            taglen -= 6;
        }
        for(et = bt; taglen && *et && (*et != ':') && !isspace(*et); ++et, --taglen) {
           // skip ':' within [ ... ]
           if (*et == '[') {
               while (taglen && *et && *et != ']') {
                   ++et;
                   --taglen;
               }
            }
        }
        for(cp = et; taglen && isspace(*cp); ++cp, --taglen);
        size_t size;

        if (*cp == ':') {
            // One Word
            tag = bt;
            etag = et;
            p = cp + 1;
        } else if (taglen) {
            size = et - bt;
            if ((taglen > size) &&   // enough space for match plus trailing :
                    (*bt == *cp) &&  // ubber fast<strncmp> pair
                    fast<strncmp>(bt + 1, cp + 1, size - 1)) {
                // <PRI>[<TIME>] <tag>_host '<tag>.<num>' : message
                if (!fast<strncmp>(bt + size - 5, "_host", 5)
                        && !fast<strncmp>(bt + 1, cp + 1, size - 6)) {
                    const char *b = cp;
                    cp += size - 5;
                    taglen -= size - 5;
                    if (*cp == '.') {
                        while (--taglen && !isspace(*++cp) && (*cp != ':'));
                        const char *e;
                        for(e = cp; taglen && isspace(*cp); ++cp, --taglen);
                        if (*cp == ':') {
                            tag = b;
                            etag = e;
                            p = cp + 1;
                        }
                    }
                } else {
                    while (--taglen && !isspace(*++cp) && (*cp != ':'));
                    const char *e;
                    for(e = cp; taglen && isspace(*cp); ++cp, --taglen);
                    // Two words
                    if (*cp == ':') {
                        tag = bt;
                        etag = e;
                        p = cp + 1;
                    }
                }
            } else if (isspace(cp[size])) {
                cp += size;
                taglen -= size;
                while (--taglen && isspace(*++cp));
                // <PRI>[<TIME>] <tag> <tag> : message
                if (*cp == ':') {
                    tag = bt;
                    etag = et;
                    p = cp + 1;
                }
            } else if (cp[size] == ':') {
                // <PRI>[<TIME>] <tag> <tag> : message
                tag = bt;
                etag = et;
                p = cp + size + 1;
            } else if ((cp[size] == '.') || isdigit(cp[size])) {
                // <PRI>[<TIME>] <tag> '<tag>.<num>' : message
                // <PRI>[<TIME>] <tag> '<tag><num>' : message
                const char *b = cp;
                cp += size;
                taglen -= size;
                while (--taglen && !isspace(*++cp) && (*cp != ':'));
                const char *e = cp;
                while (taglen && isspace(*cp)) {
                    ++cp;
                    --taglen;
                }
                if (*cp == ':') {
                    tag = b;
                    etag = e;
                    p = cp + 1;
                }
            } else {
                while (--taglen && !isspace(*++cp) && (*cp != ':'));
                const char *e = cp;
                while (taglen && isspace(*cp)) {
                    ++cp;
                    --taglen;
                }
                // Two words
                if (*cp == ':') {
                    tag = bt;
                    etag = e;
                    p = cp + 1;
                }
            }
        } /* else no tag */
        size = etag - tag;
        if ((size <= 1)
            // register names like x9
                || ((size == 2) && (isdigit(tag[0]) || isdigit(tag[1])))
            // register names like x18 but not driver names like en0
                || ((size == 3) && (isdigit(tag[1]) && isdigit(tag[2])))
            // blacklist
                || ((size == 3) && !fast<strncmp>(tag, "CPU", 3))
                || ((size == 7) && !fast<strncasecmp>(tag, "WARNING", 7))
                || ((size == 5) && !fast<strncasecmp>(tag, "ERROR", 5))
                || ((size == 4) && !fast<strncasecmp>(tag, "INFO", 4))) {
            p = start;
            etag = tag = "";
        }
    }
    // Suppress additional stutter in tag:
    //   eg: [143:healthd]healthd -> [143:healthd]
    taglen = etag - tag;
    // Mediatek-special printk induced stutter
    const char *mp = strnrchr(tag, ']', taglen);
    if (mp && (++mp < etag)) {
        size_t s = etag - mp;
        if (((s + s) < taglen) && !fast<memcmp>(mp, mp - 1 - s, s)) {
            taglen = mp - tag;
        }
    }
    // Deal with sloppy and simplistic harmless p = cp + 1 etc above.
    if (len < (size_t)(p - buf)) {
        p = &buf[len];
    }
    // skip leading space
    while ((p < &buf[len]) && (isspace(*p) || !*p)) {
        ++p;
    }
    // truncate trailing space or nuls
    size_t b = len - (p - buf);
    while (b && (isspace(p[b-1]) || !p[b-1])) {
        --b;
    }
    // trick ... allow tag with empty content to be logged. log() drops empty
    if (!b && taglen) {
        p = " ";
        b = 1;
    }
    // paranoid sanity check, can not happen ...
    if (b > LOGGER_ENTRY_MAX_PAYLOAD) {
        b = LOGGER_ENTRY_MAX_PAYLOAD;
    }
    if (taglen > LOGGER_ENTRY_MAX_PAYLOAD) {
        taglen = LOGGER_ENTRY_MAX_PAYLOAD;
    }
    // calculate buffer copy requirements
    size_t n = 1 + taglen + 1 + b + 1;
    // paranoid sanity check, first two just can not happen ...
    if ((taglen > n) || (b > n) || (n > USHRT_MAX)) {
        return -EINVAL;
    }

    // Careful.
    // We are using the stack to house the log buffer for speed reasons.
    // If we malloc'd this buffer, we could get away without n's USHRT_MAX
    // test above, but we would then required a max(n, USHRT_MAX) as
    // truncating length argument to logbuf->log() below. Gain is protection
    // of stack sanity and speedup, loss is truncated long-line content.
    char newstr[n];
    char *np = newstr;

    // Convert priority into single-byte Android logger priority
    *np = convertKernelPrioToAndroidPrio(pri);
    ++np;

    // Copy parsed tag following priority
    memcpy(np, tag, taglen);
    np += taglen;
    *np = '\0';
    ++np;

    // Copy main message to the remainder
    memcpy(np, p, b);
    np[b] = '\0';

    if (!isMonotonic()) {
        // Watch out for singular race conditions with timezone causing near
        // integer quarter-hour jumps in the time and compensate accordingly.
        // Entries will be temporal within near_seconds * 2. b/21868540
        static uint32_t vote_time[3];
        vote_time[2] = vote_time[1];
        vote_time[1] = vote_time[0];
        vote_time[0] = now.tv_sec;

        if (vote_time[1] && vote_time[2]) {
            static const unsigned near_seconds = 10;
            static const unsigned timezones_seconds = 900;
            int diff0 = (vote_time[0] - vote_time[1]) / near_seconds;
            unsigned abs0 = (diff0 < 0) ? -diff0 : diff0;
            int diff1 = (vote_time[1] - vote_time[2]) / near_seconds;
            unsigned abs1 = (diff1 < 0) ? -diff1 : diff1;
            if ((abs1 <= 1) && // last two were in agreement on timezone
                    ((abs0 + 1) % (timezones_seconds / near_seconds)) <= 2) {
                abs0 = (abs0 + 1) / (timezones_seconds / near_seconds) *
                                     timezones_seconds;
                now.tv_sec -= (diff0 < 0) ? -abs0 : abs0;
            }
        }
    }

    // Log message
    int rc = logbuf->log(LOG_ID_KERNEL, now, uid, pid, tid, newstr,
                         (unsigned short) n);

    // notify readers
    if (!rc) {
        reader->notifyNewLog();
    }

    return rc;
}
Example #30
0
int parseRequest(struct http_request * requestToFill, char * requestStr){
    char buff[FIRSTLINEBUFFSIZE]; /* This is the most we'll read */
    int i;
    int methodLoc;
    int urlEnd;
    int contentLength;
    bzero(buff,FIRSTLINEBUFFSIZE);
    bzero(requestToFill->url,MAX_URL_LENGTH);
    requestToFill->url[0] = '/'; /* Default assumption */

    /* Attempt to determine the request method */
    for(i=0; i <  FIRSTLINEBUFFSIZE && requestStr[i] != '\0'; ++i){
        if(requestStr[i] == '\r')
            if(requestStr[i+1] == '\n')
                break;
        /* Copy copy copy... */
        buff[i] = requestStr[i];
    }
    methodLoc = strnstr("GET", buff, FIRSTLINEBUFFSIZE  );
    if(methodLoc == -1){
        methodLoc = strnstr("POST", buff, FIRSTLINEBUFFSIZE );
        if(methodLoc == -1){
            methodLoc = strnstr("PUT", buff, FIRSTLINEBUFFSIZE  );
            if(methodLoc == -1){
                methodLoc = strnstr("DELETE", buff, FIRSTLINEBUFFSIZE   );
                if(methodLoc == -1){
                    /* F**k it. What'd you try to give me? */
                    NETWORK_LOG_LEVEL_1("Could not determine HTTP method. Method Not Recognized:");
                    NETWORK_LOG_LEVEL_2(buff);
                    requestToFill->method = UNKNOWN_METHOD;
                }else{
                    requestToFill->method = DELETE;
                    methodLoc+= 7; /* Advance past the method and space */
                }
            }else{
                requestToFill->method = PUT;
                methodLoc+= 4;
            }
        }else{
            requestToFill->method = POST;
            methodLoc+=5;
        }
    }else{
        requestToFill->method = GET;
        methodLoc+=4;
    }
    urlEnd = strnstr("HTTP", buff, FIRSTLINEBUFFSIZE );
    /* Find the url (Which will be between the method to the http version)*/
    i=methodLoc;
    for(methodLoc=0; methodLoc < MAX_URL_LENGTH && i < FIRSTLINEBUFFSIZE && requestStr[i] != '\0' && i < urlEnd; ++i){
        if(requestStr[i] != ' '){
            requestToFill->url[methodLoc] = requestStr[i];
            methodLoc++; /* Just re-using a variable instead of using a new one */
        }
    }
    /* Find out if there's any content: */
    contentLength = strnstr("Content-Length",requestStr,strlen(requestStr));
    if(contentLength != -1){
        /*Determine actual content length */
        contentLength+=strlen("Content-Length: "); /* Skip the text */
        methodLoc=0; /* ReUsing again */
        for(i=contentLength; methodLoc < FIRSTLINEBUFFSIZE && requestStr[i] != '\0' && requestStr[i] != '\r'; ++i)
            buff[methodLoc++] = requestStr[i];
        buff[i] = '\0';
        /* Attempt to parse: */
        contentLength = atoi(buff);

        if(contentLength > 0){
            /* If there's data than place it into the structure */
            if(requestToFill->method == POST || requestToFill->method == PUT){
                requestToFill->data = malloc(contentLength*sizeof(char)+1);
                if(requestToFill->data != NULL){
                    /* Find the content: */
                    i = strnstr("\r\n\r\n", requestStr, strlen(requestStr));
                    if(i != -1){
                        i+=4; /* skip newlines */
                        for(methodLoc = 0; i < (int)strlen(requestStr) && requestStr[i] != '\0'; ++i, ++methodLoc)
                            requestToFill->data[methodLoc] = requestStr[i];
                        requestToFill->data[methodLoc] = '\0';
                    }else{
                        /* Could not find content...*/
                        free(requestToFill->data);
                    }
                }else{
                    NETWORK_LOG_LEVEL_1("Could not allocate enough memory for content in request");
                }
            }else{
                /* Don't preallocate memory for the struct or this will cause
                 * memory not being able to be reached
                */
                requestToFill->data = NULL;
            }
        }
    }
    /* Calling parties must use contentLength to tell if they will need to free the memory */
    requestToFill->contentLength = contentLength;
    return contentLength;

    
}