Timur I. Bakeyev (b_a_t) wrote,
Timur I. Bakeyev
b_a_t

  • Mood:

Программистское. Скучное.

После 5 лет тотальной Perl лоботомии я понял, что забыл С практически начисто... Провозился 2 дня с вылизыванием 80 строчек кода :( Но до сих пор не уверен, что сделал все правильно. Так что, если кто присоветует, что тут еще можно улучщить - пишите :) Да, если по скорости какие-то оптимизации - тоже :)

Да, код под FreeBSD5 :)
#include <errno.h>
#include <sys/types.h>
#include <sys/extattr.h>
#include <stdlib.h>
#include <string.h>

#include <stdio.h>
#include <fcntl.h>

static struct {
    int space;
    const char *name;
    size_t len;
} 
extattr[] = {
	{ EXTATTR_NAMESPACE_SYSTEM, “system.”, sizeof(“system.”) },

        { EXTATTR_NAMESPACE_USER, “user.”, sizeof(“user.”) },
};

ssize_t my_listxattr (int type, const void *arg, char *list, size_t size) {
	ssize_t list_size, tot_size = 0;
	int i, t, len;
	char *buf;
	/* Iterate through extattr(2) namespaces */
	for(t = 0; t < sizeof(extattr)/sizeof(extattr[0]); t++) {
		switch(type) {
			case 0:
				list_size = extattr_list_file((const char*)arg, extattr[t].space, list, size);
				break;
			case 1:
				list_size = extattr_list_link((const char*)arg, extattr[t].space, list, size);
				break;
			case 2:
				list_size = extattr_list_fd(*(int*)arg, extattr[t].space, list, size);
				break;
			default:
				errno = ENOSYS;
				return -1;
		}
		/* Some error happened. Errno should be set by previous call */
		if(list_size < 0)
			return -1;
		/* No attributes */
		if(list_size == 0)
			continue;
		/* XXX: Call with an empty buffer may be used to calculate
		   necessary buffer size. Unfortunately, we can't say, how
		   many attributes were returned, so here is the potential
		   problem with the emulation.
		*/
		if(list == NULL) {
			/* For sure, at least one attribute exists. */
			tot_size += list_size + extattr[t].len - 1;
			continue;
		}
		/* Count necessary offset to fit namespace prefixes */
		len = 0;
		for(i = 0; i < list_size; i += list[i] + 1)
			len += extattr[t].len - 1;

		tot_size += list_size + len;
		/* Buffer is too small to fit the results */
		if(tot_size > size) {
			errno = ERANGE;
			return -1;
		}
		/* Shift the results back, so we can prepend prefixes */
		buf = memmove(list + len, list, list_size);

		for(i = 0; i < list_size; i += len + 1) {
			len = buf[i];
			strncpy(list, extattr[t].name, extattr[t].len);
			strncat(list, buf + i + 1, len);
			list += extattr[t].len + len;
		}
		size -= tot_size;
	}
	return tot_size;
}

ssize_t sys_listxattr (const char *path, char *list, size_t size)
{
	return my_listxattr(0, path, list, size);
}

ssize_t sys_llistxattr (const char *path, char *list, size_t size)
{
	return my_listxattr(1, path, list, size);
}

ssize_t sys_flistxattr (int filedes, char *list, size_t size)
{
	return my_listxattr(2, &filedes, list, size);
}

int main(int argc, char *argv[]) {
    char buf[1024];
    ssize_t size;
    int fd, i = 0;
    
    //size = sys_listxattr(argv[1], buf, sizeof(buf));
    
    fd = open(argv[1], O_RDONLY);
    
    size = sys_flistxattr(fd, buf, sizeof(buf));
    //size = sys_flistxattr(fd, NULL, 0);
    
    printf("Len: %d\n", size);
    for(i = 0; i < size; i += strlen(buf+i)+1) {
	printf("%s\n", buf+i);
    }
    return 0;
}


Кстати, не уверен, насколько верно передавать int a в функцию с void* ptr через &a, а потом приводить через *(int*)ptr. Но в теории, размера указателя может не хватить, чтобы поместить в него int(хотя до сих пор работало:)).
Subscribe

  • 45, но нифига не ягодка.

    Последние лет 5, если не больше, захожу сюда только отметить очередную прибавку в возрасте... Что поделать, ФейсБук(он же МордоКнига) поглотил нас…

  • LJ 18th anniversary

    #mylivejournal #lj18 #happybirthday

  • 42!

    Традиционный пост на День рождения :) The number 42 is, in The Hitchhiker's Guide to the Galaxy by Douglas Adams, the "Answer to the…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 59 comments

  • 45, но нифига не ягодка.

    Последние лет 5, если не больше, захожу сюда только отметить очередную прибавку в возрасте... Что поделать, ФейсБук(он же МордоКнига) поглотил нас…

  • LJ 18th anniversary

    #mylivejournal #lj18 #happybirthday

  • 42!

    Традиционный пост на День рождения :) The number 42 is, in The Hitchhiker's Guide to the Galaxy by Douglas Adams, the "Answer to the…