Skip to end of metadata
Go to start of metadata

Recursive directory converter to XML (C version)

Step-by-step guide

  1. Copy the code below
  2. Copy the Makefile
  3. Compile using "make" command
Makefile
ls2xml: ls2xml.o
        gcc -ggdb -Wall -pedantic -o ls2xml ls2xml.o

ls2xml.o: ls2xml.c
        gcc -ggdb -Wall -pedantic -c ls2xml.c

ls2xml.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <time.h>

struct entry {
        int size;
        int dir;
        int fileCount;
        int childCount;
        char *content;
        struct entry *next;
        struct entry *childs;
};

int walkdir(int indent, const char *dirname, struct entry *Parent){
        DIR *curDir;
        struct dirent *curFile;
        struct stat *curStat;
        struct tm *fileTime;
        char *newDirname;
        char *newFName;
        char *indS;
        char buf[4096];
        struct entry *here;
        struct entry *tmp;
        int cnt;
        int childNodes;

        curDir = opendir(dirname);
        here = NULL;
        if (curDir == NULL) {
                perror(dirname);
                return(-1);
        } else {
                indS = (char *)malloc(indent * 2 + 1);
                bzero(indS, indent * 2 + 1);
                memset(indS, 32, indent * 2);
                while ((curFile = readdir(curDir)) != NULL) {
                        if (strcmp(curFile->d_name, ".") == 0 ||
                                strcmp(curFile->d_name, "..") ==0)
                                continue;
                        if (here == NULL)
                        {
                                here = Parent;
                        } else {
                                here->next = (struct entry *)malloc(sizeof(struct entry));
                                bzero(here->next, sizeof(struct entry));
                                here = here->next;
                        }
                        curStat = (struct stat *)malloc(sizeof(struct stat));
                        bzero(curStat, sizeof(struct stat));
                        newFName = (char *)malloc(strlen(curFile->d_name) + 2 + strlen(dirname));
                        strcpy(newFName, dirname);
                        strcat(newFName, "/");
                        strcat(newFName, curFile->d_name);
                        if (lstat(newFName, curStat) != -1 ) {
                                if (S_ISREG(curStat->st_mode)) {
                                        here->dir = 0;
                                        fileTime = localtime(&(curStat->st_ctime));
                                        here->size = (int)(curStat->st_size);
                                        snprintf(buf, 4095, "%s<file name=\"%s\" size=\"%d\" date=\"%.4d-%.2d-%.2d\" time=\"%d:%.2d:%.2d\"/>",
                                                indS,
                                                curFile->d_name,
                                                (int)(curStat->st_size),
                                                fileTime->tm_year + 1900, fileTime->tm_mon + 1, fileTime->tm_mday, fileTime->tm_hour, fileTime->tm_min, fileTime->tm_sec);
                                        here->content = (char *)malloc(strlen(buf) + 1);
                                        strcpy(here->content, buf);
                                } else if (S_ISDIR(curStat->st_mode)) {
                                        newDirname = (char *)malloc(strlen(dirname) + strlen(curFile->d_name) + 2);
                                        strcpy(newDirname, dirname);
                                        strcat(newDirname, "/");
                                        strcat(newDirname, curFile->d_name);
                                        here->childs = (struct entry *)malloc(sizeof(struct entry));
                                        bzero(here->childs, sizeof(struct entry));
                                        walkdir(indent + 1, newDirname, here->childs);
                                        tmp = here->childs;
                                        cnt = 0;
                                        childNodes = 0;
                                        while (tmp!=NULL) {
                                                if (tmp->content != NULL) {
                                                        childNodes++;
                                                        if (tmp->dir == 0)
                                                                cnt++;
                                                        here->size += tmp->size;
                                                }
                                                tmp = tmp->next;
                                        }
                                        here->fileCount = cnt;
                                        here->childCount = childNodes;
                                        snprintf(buf, 4095, "%s<directory name=\"%s\" files=\"%d\" size=\"%d\"%s", indS, curFile->d_name, cnt, here->size, childNodes==0?"/>":">");
                                        here->dir = 1;
                                        here->content = (char *)malloc(strlen(buf) + 1);
                                        strcpy(here->content, buf);
                                        free(newDirname);
                                }
                        } else {
                                perror(curFile->d_name);
                        }
                        free(curStat);
                }
                free(indS);
                closedir(curDir);
        }
        return 1;
}

int printTree(int indent, struct entry *e){
        struct entry *t;
        char *indS;

        indS = (char *)malloc(indent * 2 + 1);
        bzero(indS, indent * 2 + 1);
        memset(indS, 32, indent * 2);

        t = e;
        while (t != NULL) {
                if (t->content !=NULL)
                        printf("%s\n", t->content);
                if (t->childs != NULL) {
                        printTree(indent + 1, t->childs);
                }
                if (t->childCount != 0) {
                        printf("%s</directory>\n", indS);
                }
                t = t->next;
        }
        return 0;
}

int main(int argc, char *argv[]){
        struct entry tree;
        struct tm *czas;
        time_t czas_t;

        czas_t = time(NULL);
        czas = localtime(&czas_t);
        bzero(&tree, sizeof(struct entry));

        if (argc == 1) {
                walkdir(1, ".", &tree);
        } else {
                walkdir(1, argv[1], &tree);
        }

        printf("<tree date=\"%.4d-%.2d-%.2d\" time=\"%d:%.2d:%.2d\">\n",
                czas->tm_year + 1900, czas->tm_mon + 1, czas->tm_mday,
                czas->tm_hour, czas->tm_min, czas->tm_sec);
        printTree(1, &tree);
        printf("</tree>\n");
        return 0;
}

/* vi:ts=2
*/


Example output
<tree date="2016-02-17" time="21:28:55">
  <directory name="lib64" files="1" size="16245">
    <file name="libfglrx_dm.so.1.0" size="16245" date="2016-02-17" time="21:28:55"/>
  </directory>
  <file name="ls2xml" size="14564" date="2018-03-21" time="18:46:56"/>
  <directory name="lib" files="1" size="12334">
    <file name="libfglrx_dm.so.1.0" size="12334" date="2016-02-17" time="21:28:55"/>
  </directory>
</tree>