04 marzo 2009

Leer a donde apunta un enlace

Hola,
en UNIX no hay "accesos directos" como los hay en Windows, sino que tenemos los enlaces, aca vamos a intentar leer a donde apunta el enlace, uno qusia hace
fopen("/proc/3341/fd/1", "r");
y nos abre directamente el archivo al que apunta "1" pero tambien podemos ver cual es el archivo verdadero.

primero que todo vamos a usar open para abrir el archivo SOLO si NO es un enlace (por si por algun motivo no quieren abrir enlaces), en open tenemos el flag O_NOFOLLOW, lo que hace es que si es un enlace NO lo sige, osea, retorna con error. en caso de no colocar este flag vamos a terminar abriendo el archivo, de esta forma podemos asegurarnos de que la ruta es un enlace


#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include errno.h
/*...*/
int fd;
/*...*/
fd = open(archivo, O_RDONLY | O_NOFOLLOW);
if(fd < 0)
{
if(errno == ELOOP)/*nos aseguramos que no lo pudimos abrir porque era un enlace*/
{
/*era un enlace!*/
}
else
{
/*no pudimos abrir el archivo por otro motivo :(*/
}
}
else
{
/*no era un enlace*/
}
/*....*/

muy bien, ahora con otra funcion podemos leer a donde apunta el enlace, esa funcion se llama readlink(), si solo queremos saber si es un enlace o no podemos usamos readlink(), nos retorna -1 si hubo error (probablemente porque no era un enlace) y si era un enlace, nos dice a donde apunta
ssize_t readlink(const char *path, char *buf, size_t bufsiz);
path es la ruta del archivo, buf es un array donde va a poner a donde apunta y bufsiz la cantidad maxima de caracteres a copiar en buf


#include errno.h
#include unistd.h
/*...*/
char out[300];
ssize_t s;
/*...*/
s = readlink(archivo, out, 300);
if(s < 0)
{
if(errno == EINVAL)
{
/*no era un enlace*/
}
else
{
/*otro error*/
}
}
else
{
/*era un enlace! y a donde apunta esta en out*/
}
/*...*/

el problema con readlink es que no coloca el caracter \0 al final de la cadena, eso se arregla de esta manera:

/*siguiendo con el s = readlink(archivo, out, 300); */
out[s] = 0;

bueno eso es todo, ya saben como no abrir enlaces con open, como fijarse si una ruta es un enlace o no con readlink y como saber a donde apunta un elnace con readlink

salu2!