T
thoseion
Hi, I am trying to get a program working whereby directory and file
names are read into a list. I have been given the original list
structure - it appears that the directory names should be added to the
list, then the filenames added to another separate but connected list
within each directory node.
So far I have the program working in that the directory and file names
are all added to the list, i.e. it currently doesn't distinguish
between directories/files, and I can print the contents out. I'm
really not sure how to go about adding the filenames to the content
list though so any help would be very much appreciated.
------------------------------------------------------------------------------------------------------------
enum Tnodetype {n_file, n_directory, n_symlink};
typedef enum Tnodetype Nodetype;
struct Tcell{
struct Tcell *next;
char * localname;
char * fullname;
struct Tcell * content; // list of files in directory
Nodetype nodetype;
};
typedef struct Tcell Cell, *List;
char * fullname(char *root, char * name)
{
const char * sep = "/";
char * res = (char *)
malloc(strlen(root)+strlen(sep)+strlen(name)+1);
strcpy(res,root);
strcat(res,sep);
strcat(res,name);
return res;
}
int notdot (char * s)
{
return strcmp(s,".") != 0 && strcmp(s,"..")!= 0 ;
}
int issymlink(char * name)
{
struct stat buf;
lstat(name, &buf);
return (buf.st_mode & S_IFMT) == S_IFLNK;
}
int isdir(char * name)
{
struct stat buf;
lstat(name, &buf);
return (buf.st_mode & S_IFMT) == S_IFDIR;
}
List cons(List lp, char * fname, char * lname, Nodetype nodetype)
{
List res = (List)malloc(sizeof(Cell));
res->localname = strdup(lname);
res->fullname = strdup(fname);
res->nodetype = nodetype;
res->next = lp;
return res;
}
List add_symlink(List lp, char *path, char * name)
{
Nodetype nodetype = n_symlink;
return cons(lp, path, name, n_symlink);
return lp;
}
List add_directory(List lp, char *path, char * name)
{
Nodetype nodetype = n_directory;
return cons(lp, path, name, n_directory);
return lp;
}
List add_file(List lp, char *path, char * name)
{
Nodetype nodetype = n_file;
return cons(lp, path, name, n_file);
return lp;
}
List filecheck(List lp, char * dirname)
{
DIR *dd;
struct dirent *dp;
int res = 0;
dd = opendir(dirname);
assert(dd);
while ((dp = readdir(dd)))
if (notdot(dp->d_name)){
char * name2 = fullname(dirname, dp->d_name);
if (issymlink(name2))
lp = add_symlink(lp, name2, dp->d_name);
else if (isdir(name2)){
lp = add_directory(filecheck(lp,name2), name2,
dp->d_name);
}
else
lp = add_file(lp, name2, dp->d_name);
}
closedir(dd);
return lp;
}
void showtree (List lp)
{
for ( ; lp ; lp = lp->next)
printf(" %s\n",lp->fullname);
}
int main(int argc, char * argv[]) {
List lp = 0;
char * dirname = strdup(( argc >1) ? argv[1] : getenv("HOME"));
showtree(filecheck(lp, dirname));
return (0);
}
-------------------------------------------------------------------------------------------------------------
names are read into a list. I have been given the original list
structure - it appears that the directory names should be added to the
list, then the filenames added to another separate but connected list
within each directory node.
So far I have the program working in that the directory and file names
are all added to the list, i.e. it currently doesn't distinguish
between directories/files, and I can print the contents out. I'm
really not sure how to go about adding the filenames to the content
list though so any help would be very much appreciated.
------------------------------------------------------------------------------------------------------------
enum Tnodetype {n_file, n_directory, n_symlink};
typedef enum Tnodetype Nodetype;
struct Tcell{
struct Tcell *next;
char * localname;
char * fullname;
struct Tcell * content; // list of files in directory
Nodetype nodetype;
};
typedef struct Tcell Cell, *List;
char * fullname(char *root, char * name)
{
const char * sep = "/";
char * res = (char *)
malloc(strlen(root)+strlen(sep)+strlen(name)+1);
strcpy(res,root);
strcat(res,sep);
strcat(res,name);
return res;
}
int notdot (char * s)
{
return strcmp(s,".") != 0 && strcmp(s,"..")!= 0 ;
}
int issymlink(char * name)
{
struct stat buf;
lstat(name, &buf);
return (buf.st_mode & S_IFMT) == S_IFLNK;
}
int isdir(char * name)
{
struct stat buf;
lstat(name, &buf);
return (buf.st_mode & S_IFMT) == S_IFDIR;
}
List cons(List lp, char * fname, char * lname, Nodetype nodetype)
{
List res = (List)malloc(sizeof(Cell));
res->localname = strdup(lname);
res->fullname = strdup(fname);
res->nodetype = nodetype;
res->next = lp;
return res;
}
List add_symlink(List lp, char *path, char * name)
{
Nodetype nodetype = n_symlink;
return cons(lp, path, name, n_symlink);
return lp;
}
List add_directory(List lp, char *path, char * name)
{
Nodetype nodetype = n_directory;
return cons(lp, path, name, n_directory);
return lp;
}
List add_file(List lp, char *path, char * name)
{
Nodetype nodetype = n_file;
return cons(lp, path, name, n_file);
return lp;
}
List filecheck(List lp, char * dirname)
{
DIR *dd;
struct dirent *dp;
int res = 0;
dd = opendir(dirname);
assert(dd);
while ((dp = readdir(dd)))
if (notdot(dp->d_name)){
char * name2 = fullname(dirname, dp->d_name);
if (issymlink(name2))
lp = add_symlink(lp, name2, dp->d_name);
else if (isdir(name2)){
lp = add_directory(filecheck(lp,name2), name2,
dp->d_name);
}
else
lp = add_file(lp, name2, dp->d_name);
}
closedir(dd);
return lp;
}
void showtree (List lp)
{
for ( ; lp ; lp = lp->next)
printf(" %s\n",lp->fullname);
}
int main(int argc, char * argv[]) {
List lp = 0;
char * dirname = strdup(( argc >1) ? argv[1] : getenv("HOME"));
showtree(filecheck(lp, dirname));
return (0);
}
-------------------------------------------------------------------------------------------------------------