示例#1
0
static void test_kstr() {
    kstr str1, str2, str3;
    kstr_init(&str1);
    kstr_init_cstr(&str2, "bar");
    kstr_init_kstr(&str3, &str2);

    assert(kstr_equal_cstr(&str2, "bar"));
    assert(kstr_equal_kstr(&str2, &str3));

    kstr_assign_cstr(&str3, "foobar");
    kstr_assign_kstr(&str1, &str3);
    kstr_sf(&str2, "%sbar", "foo");
    
    assert(kstr_equal_kstr(&str3, &str2));
    assert(kstr_equal_kstr(&str1, &str2));

    kstr_sf(&str2, "%s buffer to grow", "I want my");
    assert(kstr_equal_cstr(&str2, "I want my buffer to grow"));

    kstr_clear(&str2);
    assert(kstr_equal_cstr(&str2, ""));
    
    kstr_append_char(&str2, 'f');
    kstr_append_char(&str2, 'o');
    kstr_assign_cstr(&str1, "ob");
    kstr_append_kstr(&str2, &str1);
    kstr_append_cstr(&str2, "ar");
    assert(kstr_equal_cstr(&str2, "foobar"));

    kstr_free(&str1);
    kstr_free(&str2);
    kstr_free(&str3);
}
示例#2
0
/* This function normalizes a path. It simplifies the directory portion and
 * makes the path absolute if requested.
 */
void kpath_normalize(kstr *path, int absolute_flag, int format) {
    struct kpath_dir dir;
    kstr dir_path, filename, ext;
    
    kstr_init(&dir_path);
    kstr_init(&filename);
    kstr_init(&ext);
    kpath_dir_init(&dir);
    
    /* If requested, make the path absolute. */
    if (absolute_flag) kpath_make_absolute(path, format);
    
    /* Split the path. */
    kpath_split(path, &dir_path, &filename, &ext, format);
    
    /* Decompose, simplify and recompose the directory portion. */
    kpath_decompose_dir(&dir_path, &dir, format);
    kpath_simplify_dir(&dir);
    kpath_recompose_dir(&dir_path, &dir, format);
    
    /* Recompose the path. */
    kstr_assign_kstr(path, &dir_path);
    kstr_append_kstr(path, &filename);
    
    if (ext.slen) {
        kstr_append_char(path, '.');
        kstr_append_kstr(path, &ext);
    }
    
    kpath_dir_clean(&dir);
    kstr_clean(&dir_path);
    kstr_clean(&filename);
    kstr_clean(&ext);
}
示例#3
0
/* This function recomposes a directory path from its subcomponents. If the
 * directory path has no absolute part and no other components, the directory
 * path will be empty. Otherwise, the directory path will end with a delimiter.
 */
void kpath_recompose_dir(kstr *path, struct kpath_dir *dir, int format) {
    int i;
    
    kstr_reset(path);
    
    if (dir->abs_part.slen) kstr_assign_kstr(path, &dir->abs_part);
    
    for (i = 0; i < dir->components.size; i++) {
        kstr_append_kstr(path, (kstr *) dir->components.data[i]);
        kstr_append_char(path, kpath_delim(format));
    }
}
示例#4
0
/** Converts a DNS name to a domain DN.
 * 
 * Example: AD.LOCAL => DC=AD,DC=LOCAL.
 *
 * This is very much AD specific.  It won't work for Lotus Domino DNs.
 */
char *kdldap_DNS_to_dn(apr_pool_t *pool, const char *dns_dom) {
    kstr r;
    const char *s = dns_dom;
    char *dn;
    
    kstr_init_cstr(&r, "DC=");
    
    while (*s) {
        if (*s == '.') kstr_append_cstr(&r, ",DC=");
        else kstr_append_char(&r, *s);
        s++;
    }
    
    dn = apr_pstrdup(pool, r.data);
    kstr_clean(&r);
    
    return dn;
}
示例#5
0
文件: kstr.c 项目: miraeye/f265
/* Replace all occurences of the string 'from' with the string 'to' in the
 * string specified.
 */
void kstr_replace(kstr *self, char *from, char *to) {
    kstr tmp;
    int i = 0;
    int l = strlen(from);
    
    assert(l);
    kstr_init(&tmp);
    
    while (i < self->slen) {
        if (! strncmp(self->data + i, from, l)) {
            kstr_append_cstr(&tmp, to);
            i += l;
        }
        
        else {
            kstr_append_char(&tmp, self->data[i]);
            i++;
        }
    }
    
    kstr_assign_kstr(self, &tmp);
    kstr_clean(&tmp);
}
示例#6
0
文件: knp.c 项目: fdgonthier/kmod
/* This function asks the proxy to connect us to the end server.
 * This function sets the KMO error string. It returns 0, -1, -2 or -3.
 */
static int knp_handle_proxy(struct knp_query *query, k3p_proto *k3p, kstr *proxy_login, kstr *proxy_pwd) {
    int error = 0;
    int first_line = 1;
    struct kmo_data_transfer *transfer = &query->transfer;
    kstr msg;
    kstr str;
    
    kmod_log_msg(3, "knp_handle_proxy() called.\n");
    
    kstr_init(&msg);
    kstr_init(&str);
	
    /* Try. */
    do {
	/* Connect to the specified server and port. */
	kstr_sf(&msg, "CONNECT %s:%d HTTP/1.0\r\n", query->server_addr.data, query->server_port);
    	
	/* Using the following "user:pwd" credentials encoded in base 64. */
	if (proxy_login->slen > 0 || proxy_pwd->slen > 0) {
	    kbuffer in, out;
	    kbuffer_init(&in, 100);
	    kbuffer_init(&out, 100);
	    
	    kbuffer_write(&in, proxy_login->data, proxy_login->slen);
	    kbuffer_write(&in, ":", 1);
	    kbuffer_write(&in, proxy_pwd->data, proxy_pwd->slen);
	    bin2b64(&in, &out);
	    
	    kstr_append_cstr(&msg, "Proxy-Authorization: basic ");
	    kstr_append_buf(&msg, out.data, out.len);
	    kstr_append_cstr(&msg, "\r\n");
	    
	    kbuffer_clean(&in);
	    kbuffer_clean(&out);
	}
	
	/* An empty line marks the end of the request. */
	kstr_append_cstr(&msg, "\r\n");
	
	/* Send the message to the proxy. */
	transfer->read_flag = 0;
	transfer->buf = msg.data;
	transfer->min_len = transfer->max_len = msg.slen;
	error = knp_exec_transfer(transfer, k3p);
	if (error) break;
	
	if (transfer->status != KMO_COMM_TRANS_COMPLETED) {
	    assert(transfer->status == KMO_COMM_TRANS_ERROR);
	    kmo_seterror("proxy error: %s", kmo_data_transfer_err(transfer));
	    knp_query_handle_conn_error(query, transfer->err_msg ? KMO_SERROR_MISC : KMO_SERROR_TIMEOUT);
	    error = -1;
	    break;
	}
    
    	/* Receive the reply from the server, char by char to avoid reading past 
	 * the HTTP reply data.
	 */
	kstr_clear(&msg);
	
	while (1) {
	    char c;
	    transfer->read_flag = 1;
	    transfer->buf = &c;
	    transfer->min_len = transfer->max_len = 1;
	    error = knp_exec_transfer(transfer, k3p);
	    if (error) break;

	    if (transfer->status != KMO_COMM_TRANS_COMPLETED) {
		assert(transfer->status == KMO_COMM_TRANS_ERROR);
		kmo_seterror("proxy error: %s", kmo_data_transfer_err(transfer));
		knp_query_handle_conn_error(query, transfer->err_msg ? KMO_SERROR_MISC : KMO_SERROR_TIMEOUT);
		error = -1;
		break;
	    }
	    
	    kstr_append_char(&msg, c);
	    
	    /* We reached the end of a line. */
	    if (msg.slen >= 2 && msg.data[msg.slen - 2] == '\r' && msg.data[msg.slen - 1] == '\n') {
	    	
		/* This is the response line. Parse it. */
		if (first_line) {
		    int reply_code;
		    
		    /* Expecting "HTTP/x.x ddd <string>\r\n" */
		    if (msg.slen < 16 || msg.data[0] != 'H' || msg.data[1] != 'T' || msg.data[2] != 'T' ||
		        msg.data[3] != 'P' || ! is_digit(msg.data[9]) || ! is_digit(msg.data[10]) ||
			! is_digit(msg.data[11])) {
			
		    	kmo_seterror("invalid proxy HTTP reply");
		    	error = -1;
			break;
		    }
		    
		    /* Get the numeric code. */
		    reply_code = atoi(msg.data + 9);
		    
		    /* Not 200, it didn't work. */
		    if (reply_code != 200) {
		    	
		    	/* Get the reason. */
		    	kstr_assign_buf(&str, msg.data + 13, msg.slen - 2 - 13);
			kmo_seterror("the proxy refuses to connect: %s (code %d)", str.data, reply_code);
			error = -1;
			break;
		    }
		    
		    first_line = 0;
		}
		
		/* The server is sending us some unwanted line. Ignore it. */
		else if (msg.slen != 2) {
		    /* Void. */
		}
		
		/* We reached the end of the reply. The next bytes received will be SSL bytes. */
		else {
		    break;
		}
		
		/* Clear the line buffer. */
	    	kstr_clear(&msg);
	    }
	    
	    /* It's too long. */
	    else if (msg.slen > 1000) {
	    	kmo_seterror("HTTP reply too long");
    	    	error = -1;
		break;
	    }
	}
	
	if (error) break;
    
    } while (0);
    
    kstr_free(&msg);
    kstr_free(&str);
    
    return error;
}
示例#7
0
/* This function splits the path into 3 components, directory (with trailing
 * delimiter), file name (without extension), and extension (without '.').
 *
 * The path '/etc/ld.so.conf' will yield directory '/etc/', file name 'ld', and extension 'so.conf'.
 * The path '/etc/' will yield directory '/etc/', file name '', and extension ''.
 * The path '/etc' will yield directory '/', file name 'etc', and extension ''.
 * The path 'foo.' will yield directory './', file name 'foo.' and extension '', i.e. the extension must not be empty.
 * The path '.foo' will yield directory './', file name '.foo' and extension '', i.e. the file name must not be empty.
 * The path '.' will yield directory './', file name '', and extension ''.
 * The path '..' will yield directory '../', file name '', and extension ''.
 * The path '' will yield directory '', file name '', and extension ''.
 * Rule of thumb: If the extension is not empty, then <dir><filename>.<extension> is the path.
 *		  If the extension is empty, then <dir><filename> is the path.
 * Arguments:
 * String containing the path.
 * Directory string pointer, can be NULL.
 * File name string pointer, can be NULL.
 * Extension string pointer, can be NULL.
 */
void kpath_split(kstr *path, kstr *dir, kstr *name, kstr *ext, int format) {
    int i;
    int last_delim_pos = -1;
    int filename_start_pos = 0;
    int first_dot_pos = -1;
    
    /* Locate the last path delimiter, if any. */
    for (i = path->slen - 1; i >= 0; i--) {
        if (kpath_is_delim(path->data[i], format)) {
            last_delim_pos = i;
            break;
        }
    }
    
    /* Check if the next characters after the last delimiter, or the first
     * characters if there is no last delimiter, are exactly and no more than
     * '.' or '..'. In that case, consider the whole path to be a directory
     * path.
     */
    if (last_delim_pos != -1) filename_start_pos = last_delim_pos + 1;
    if (! strcmp(path->data + filename_start_pos, ".")) filename_start_pos += 1;
    else if (! strcmp(path->data + filename_start_pos, "..")) filename_start_pos += 2;
    
    /* Locate the first dot in the file name, if any. */
    for (i = filename_start_pos; i < path->slen; i++) {
        
        /* We found a dot. */
        if (path->data[i] == '.') {
            
            /* If there's nothing before or after the dot, consider there is no dot. */
            if (i != filename_start_pos && i != path->slen - 1) first_dot_pos = i;
            break;
        }
    }

    /* Get the directory portion. */
    if (dir) {
    
        /* Empty path. */
        if (! path->slen) kstr_reset(dir);
        
        /* Relative path with no directory specified. */
        else if (! filename_start_pos) kstr_sf(dir, ".%c", kpath_delim(format)); 
        
        /* Directory present. Extract the directory and add a delimiter if
         * required.
         */
        else {
            kstr_mid(path, dir, 0, filename_start_pos);
            if (! kpath_is_delim(dir->data[dir->slen - 1], format)) kstr_append_char(dir, kpath_delim(format));
        }
    }

    /* Get the file name. */
    if (name) {
        int filename_size;

        /* No extension case. */
        if (first_dot_pos == -1) filename_size = path->slen - filename_start_pos;

        /* Extension case. */
        else filename_size = first_dot_pos - filename_start_pos;
        
        kstr_mid(path, name, filename_start_pos, filename_size);
    }

    /* Get the extension. */
    if (ext) {
    
        /* No extension case. */
        if (first_dot_pos == -1) kstr_reset(ext);

        /* Extension case. */
        else kstr_mid(path, ext, first_dot_pos + 1, path->slen - first_dot_pos - 1);
    }
}
示例#8
0
/* This function adds a trailing delimiter to the string specified if one is not
 * already present and if the string is non-empty.
 */
void kpath_add_delim(kstr *path, int format) {
    if (path->slen && ! kpath_is_delim(path->data[path->slen - 1], format)) {
        kstr_append_char(path, kpath_delim(format));
    }
}
示例#9
0
/* This function decomposes the directory path specified into an array of
 * subcomponents. If the path is absolute, the absolute part will be something
 * like 'C:\' on Windows and '/' on UNIX, otherwise it will be empty. The
 * remaining components will not contain delimiters.
 *
 * The path 'C:/toto/bar' will yield ('C:\', 'toto', 'bar') on Windows with alt
 * support.
 * The path '/toto/bar/' will yield ('/', 'toto', 'bar') on UNIX.
 * The path './../foo/' will yield ('.', '..', 'foo').
 * The path '' will yield ().
 */
void kpath_decompose_dir(kstr *path, struct kpath_dir *dir, int format) {
    int scan_pos = 0;
    kstr cur_component;
    
    /* Get the platform format. */
    int platform_format = kpath_get_platform_format(format);
    
    /* Determine if the path is absolute. */
    int is_absolute = kpath_is_absolute(path, format);
    
    kstr_init(&cur_component);
    kpath_dir_reset(dir);
    
    /* If the path is absolute, obtain the absolute part. */
    if (is_absolute) {
    
        if (platform_format == KPATH_FORMAT_UNIX) {
            kstr_append_char(&dir->abs_part, '/');
            scan_pos = 1;
        }
        
        else {
            kstr_append_buf(&dir->abs_part, path->data, 2);
            kstr_append_char(&dir->abs_part, kpath_delim(format));
            scan_pos = 3;
        }
    }
    
    /* Scan the rest of the path. */
    while (scan_pos < path->slen) {
        
        /* We encountered a delimiter. */
        if (kpath_is_delim(path->data[scan_pos], format)) {
            
            /* If the current component is empty, ignore it. Otherwise, add the
             * component in the component array.
             */
            if (cur_component.slen) {
                kstr *s = kstr_new();
                kstr_assign_kstr(s, &cur_component);
                karray_push(&dir->components, s);
            }
            
            /* Reset the current component. */
            kstr_reset(&cur_component);
        }
        
        /* Append the current character. */
        else kstr_append_char(&cur_component, path->data[scan_pos]);
        
        scan_pos++;
    }
    
    /* Add the last component, if any, in the component array. */
    if (cur_component.slen) {
        kstr *s = kstr_new();
        kstr_assign_kstr(s, &cur_component);
        karray_push(&dir->components, s);
    }
    
    kstr_clean(&cur_component);
}