Exemple #1
0
/* Same as anp_dump(), but the header of the message is also dumped. */
int anp_msg_dump(struct anp_msg *self, kstr *dump_str) {
    int error = 0;
    kstr work_str;
    
    kstr_init(&work_str);
    kstr_reset(dump_str);

    kstr_sf(&work_str, "major> %u\n", self->major);
    kstr_append_kstr(dump_str, &work_str);

    kstr_sf(&work_str, "minor> %u\n", self->minor);
    kstr_append_kstr(dump_str, &work_str);

    kstr_sf(&work_str, "type> %u\n", self->minor);
    kstr_append_kstr(dump_str, &work_str);

    kstr_sf(&work_str, "id> "PRINTF_64"u\n", self->minor);
    kstr_append_kstr(dump_str, &work_str);

    if (anp_dump(&self->payload, &work_str)) {
        error = -1;
    } else {
        kstr_append_kstr(dump_str, &work_str);
    }

    kstr_clean(&work_str);
    return error;
}
Exemple #2
0
/* FIXME: In Blackjack this function should become generally available. */
void format_current_error_for_user(kstr *dest) {
    struct kerror *error_instance = kerror_get_current();
    int i;
    
    kstr_reset(dest);

    if (error_instance->stack.size == 0) {
        kstr_assign_cstr(dest, "unknown error");
    }
    
    else {
	for (i = error_instance->stack.size - 1; i >= 0; i--) {
	    struct kerror_node *node = (struct kerror_node *) karray_get(&error_instance->stack, i);
            /* Level 1 error are meant to be readable. */	    
            if (node->level >= 1) {
                if (i != error_instance->stack.size - 1) {
                    kstr_append_cstr(dest, ": ");
                }
            
                    kstr_append_kstr(dest, &node->text);
            }
	}
    }

    if (dest->slen == 0) 
        kstr_assign_cstr(dest, "unknown error");
}
Exemple #3
0
/* This function ensures that the string specified does not get too large. If
 * the internal memory associated to the string is bigger than the threshold
 * specified, the memory associated to the string is released and a new, small
 * buffer is allocated for the string. In all cases, the string is cleared.
 */
void kstr_shrink(kstr *self, int max_size) {
    if (self->slen > max_size) {
    	kstr_clean(self);
	kstr_init(self);
    }
    
    kstr_reset(self);
}
Exemple #4
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));
    }
}
Exemple #5
0
void kstr_sfv(kstr *self, const char *format, va_list arg) {
    kstr_reset(self);
    kstr_append_sfv(self, format, arg);
}
Exemple #6
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);
    }
}
Exemple #7
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);
}
Exemple #8
0
void kpath_dir_reset(struct kpath_dir *self) {
    int i = 0;
    kstr_reset(&self->abs_part);
    for (i = 0; i < self->components.size; i++) kstr_destroy((kstr *) self->components.data[i]);
    karray_reset(&self->components);
}
Exemple #9
0
/* This function dumps the content of a ANP message buffer in the string
 * specified. This function sets the KMOD error string when it encounters an
 * error in the buffer. It returns -1 on failure.
 */
int anp_dump(kbuffer *buf, kstr *dump_str) {
    int error = 0;
    kstr work_str;
    kstr data_str;
    kbuffer bin_buf;
    
    kstr_init(&work_str);
    kstr_init(&data_str);
    kbuffer_init(&bin_buf);
    kstr_reset(dump_str);

    while (! kbuffer_eof(buf)) {
	uint8_t type = buf->data[buf->pos];
	
	if (type == ANP_UINT32) {
	    uint32_t val;
	    error = anp_read_uint32(buf, &val);
	    if (error) break;
	    
	    kstr_sf(&work_str, "uint32> %u\n", val);
	    kstr_append_kstr(dump_str, &work_str);
	}
	
	else if (type == ANP_UINT64) {
	    uint64_t val;
	    error = anp_read_uint64(buf, &val);
	    if (error) break;
	    
	    kstr_sf(&work_str, "uint64> "PRINTF_64"u\n", val);
	    kstr_append_kstr(dump_str, &work_str);
	}
	
	else if (type == ANP_STR) {
	    error = anp_read_kstr(buf, &data_str);
	    if (error) break;
	
	    kstr_sf(&work_str, "string %u> ", data_str.slen);
	    kstr_append_kstr(dump_str, &work_str);
	    kstr_append_kstr(dump_str, &data_str);
	    kstr_append_cstr(dump_str, "\n");
	}
	
	else if (type == ANP_BIN) {
	    error = anp_read_bin(buf, &bin_buf);
	    if (error) break;
	
	    kstr_sf(&work_str, "binary %u> ", bin_buf.len);
	    kstr_append_kstr(dump_str, &work_str);
	    kstr_append_cstr(dump_str, "\n");
	}
	
	else {
	    kmod_set_error("invalid ANP identifier (%u)\n", type);
	    error = -1;
	    break;
	}
    }
    
    kstr_clean(&work_str);
    kstr_clean(&data_str);
    kbuffer_clean(&bin_buf);
    
    /* Reset the buffer position to 0. */
    buf->pos = 0;
    
    return error;
}