1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| //douviensje.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
#define SEP '/'
void split_path(char *pathname, char *dirname, char *basename)
{
char *ptr = strrchr(pathname,SEP);
if (ptr)
{
strncpy(dirname,pathname,ptr-pathname);
dirname[ptr-pathname] = '\0';
strcpy(basename,ptr+1);
}
else
{
strcpy(dirname,".");
strcpy(basename,pathname);
}
}
int follow_links(char *start, char *stop)
{
struct stat struct_stat;
char iwd[PATH_MAX];
char dirname[PATH_MAX];
char basename[PATH_MAX];
size_t size;
int code = 0;
getcwd(iwd,PATH_MAX); // pour pouvoir y revenir
strcpy(stop,start); // path courant au debut
while (1)
{
// separation dirname - basename
split_path(stop,dirname,basename);
// deplacement dans dirname, lecture infos basename
if (chdir(dirname) || lstat(basename,&struct_stat))
{ code = -1; break; }
// sortie de la boucle infinie
if (!S_ISLNK(struct_stat.st_mode))
break;
// lecture du lien symbolique
size = readlink(basename,stop,PATH_MAX);
stop[size] = '\0';
// pour suivre le deroulement
fprintf(stderr,"passage par %s\n",stop);
}
getcwd(dirname,PATH_MAX); // pour avoir le chemin absolu
sprintf(stop,"%s%c%s",dirname,SEP,basename);
chdir(iwd); // retour a la case depart
return code;
}
int main(int argc,char *argv[])
{
FILE *pipe;
char buffer[PATH_MAX];
char pathname[PATH_MAX];
// lecture du chemin vers l'executable
sprintf(buffer,"which %s",argv[0]);
pipe = popen(buffer,"r");
fgets(buffer,PATH_MAX,pipe);
buffer[strlen(buffer)-1]='\0';
pclose(pipe);
if (follow_links(buffer,pathname))
fprintf(stderr,"lien casse ?\n");
else
fprintf(stderr,"%s\n",pathname);
} |