fork(1) download
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <getopt.h>
  5.  
  6. typedef struct _vfs_stack
  7. {
  8. struct _vfs_stack *nxt;
  9. void *ptr;
  10. } vfs_stack;
  11.  
  12. typedef struct _vfs_file
  13. {
  14. char *virt_file_name;
  15. char *virt_file_real_path;
  16. char *virt_file_gname;
  17. char *virt_file_uname;
  18. char *virt_file_perms;
  19. } vfs_file;
  20.  
  21. typedef struct _vfs_dir
  22. {
  23. struct _vfs_dir *dirs, *parent;
  24. //vfs_file *dir_files;
  25.  
  26. int n_virt_dirs;
  27. //int n_virt_files;
  28.  
  29. char *virt_dir_name;
  30. //char *virt_dir_gname;
  31. //char *virt_dir_uname;
  32. //char *virt_dir_perms;
  33. } vfs_dir;
  34.  
  35.  
  36. void *vfs_stack_pop(vfs_stack **head)
  37. {
  38. if (!head)
  39. return NULL;
  40.  
  41. vfs_stack *temp = *head;
  42. void *ptr = (*head)->ptr;
  43. *head = (*head)->nxt;
  44.  
  45. free(temp);
  46.  
  47. return ptr;
  48. }
  49.  
  50. void vfs_stack_push(vfs_stack **head, void *ptr)
  51. {
  52. if (!head || !ptr)
  53. return;
  54.  
  55. vfs_stack *push = calloc(1, sizeof(vfs_stack));
  56. if (!push)
  57. return;
  58.  
  59. push->ptr = ptr;
  60. push->nxt = *head;
  61. *head = push;
  62. }
  63.  
  64. vfs_dir *vfs_mkdir(vfs_dir **parent, char *ftp_dir_name)
  65. {
  66. if (!parent)
  67. {
  68. vfs_dir *vfs_ret = calloc(1, sizeof(vfs_dir));
  69. if (vfs_ret)
  70. {
  71. vfs_ret->n_virt_dirs = 0;
  72. vfs_ret->parent = NULL;
  73. vfs_ret->dirs = NULL;
  74.  
  75. if (ftp_dir_name)
  76. vfs_ret->virt_dir_name = strdup(ftp_dir_name);
  77. else
  78. vfs_ret->virt_dir_name = NULL;
  79. }
  80.  
  81. return vfs_ret;
  82. }
  83.  
  84. if (!(*parent)->n_virt_dirs)
  85. (*parent)->dirs = calloc(1, sizeof(vfs_dir));
  86. else
  87. {
  88. vfs_dir *dir_temp = realloc((*parent)->dirs, (((*parent)->n_virt_dirs + 1) * sizeof(vfs_dir)));
  89. if (dir_temp)
  90. (*parent)->dirs = dir_temp;
  91. else
  92. {
  93. free((*parent)->dirs);
  94. return NULL;
  95. }
  96. }
  97.  
  98. (*parent)->dirs[(*parent)->n_virt_dirs].virt_dir_name = strdup(ftp_dir_name);
  99. (*parent)->dirs[(*parent)->n_virt_dirs].parent = *parent;
  100. (*parent)->dirs[(*parent)->n_virt_dirs].n_virt_dirs = 0;
  101. (*parent)->dirs[(*parent)->n_virt_dirs].dirs = 0;
  102.  
  103. return &(*parent)->dirs[(*parent)->n_virt_dirs++];
  104. }
  105.  
  106. void vfs_rmdir(vfs_dir *pfs_dir)
  107. {
  108. if (!pfs_dir)
  109. return;
  110.  
  111. vfs_stack *head = NULL;
  112.  
  113. // Initialise stack of directories to free with lowest level directory.
  114. vfs_stack_push(&head, pfs_dir);
  115.  
  116. vfs_dir *pop = 0;
  117. while (head)
  118. {
  119. // pop our directory off the stack.
  120. pop = (vfs_dir *)vfs_stack_pop(&head);
  121.  
  122. if (pop)
  123. {
  124. if (pop->n_virt_dirs) // are there more directories within this one?
  125. {
  126. for (int i = 0; i < pop->n_virt_dirs; i++)
  127. {
  128. vfs_dir *pfs_temp = &pop->dirs[i];
  129. vfs_stack_push(&head, pfs_temp); // push them to the stack so we can wipe its owner.
  130.  
  131. }
  132. pop->n_virt_dirs = 0;
  133. }
  134.  
  135. printf("Freeing %s\n", pop->virt_dir_name);
  136. // cleanup this folder level as we've saved its children.
  137. }
  138. }
  139. free(pfs_dir);
  140. }
  141.  
  142. int main(int argc, char **argv)
  143. {
  144. vfs_dir *pfs_root = vfs_mkdir(NULL, "/");
  145. if (!pfs_root)
  146. {
  147. perror("vfs_mkdir root");
  148. exit(-1);
  149. }
  150.  
  151. printf("Virtual filesystem root created: pfs_root\n\n");
  152.  
  153. vfs_mkdir(&pfs_root, "Folder 1");
  154. vfs_mkdir(&pfs_root, "Folder 2");
  155. vfs_mkdir(&pfs_root, "Folder 3");
  156.  
  157.  
  158. printf("%s has %d folders\n", pfs_root->virt_dir_name, pfs_root->n_virt_dirs);
  159. printf("Dir 1: %s%s\n", pfs_root->virt_dir_name, pfs_root->dirs[0].virt_dir_name);
  160. printf("Dir 2: %s%s\n", pfs_root->virt_dir_name, pfs_root->dirs[1].virt_dir_name);
  161. printf("Dir 3: %s%s\n\n", pfs_root->virt_dir_name, pfs_root->dirs[2].virt_dir_name);
  162.  
  163. vfs_dir *new_level_dir = &pfs_root->dirs[0];
  164. vfs_mkdir(&new_level_dir, "Folder 1-1");
  165.  
  166. printf("%s has %d folders\n", pfs_root->dirs[0].virt_dir_name, new_level_dir->n_virt_dirs);
  167. printf("Dir 4: %s%s/%s\n\n", pfs_root->virt_dir_name, pfs_root->dirs[0].virt_dir_name, new_level_dir->dirs[0].virt_dir_name);
  168.  
  169. vfs_dir *deeper_dir = &new_level_dir->dirs[0];
  170. vfs_mkdir(&deeper_dir, "Folder 1-1-1");
  171. vfs_mkdir(&deeper_dir, "Folder 1-1-2");
  172.  
  173.  
  174. printf("%s has %d folders\n", new_level_dir->dirs[0].virt_dir_name, deeper_dir->n_virt_dirs);
  175. printf("Dir 5: %s%s/%s/%s\n", pfs_root->virt_dir_name, pfs_root->dirs[0].virt_dir_name, new_level_dir->dirs[0].virt_dir_name, deeper_dir->dirs[0].virt_dir_name);
  176. printf("Dir 6: %s%s/%s/%s\n\n", pfs_root->virt_dir_name, pfs_root->dirs[0].virt_dir_name, new_level_dir->dirs[0].virt_dir_name, deeper_dir->dirs[1].virt_dir_name);
  177.  
  178. vfs_rmdir(pfs_root);
  179.  
  180. return 0;
  181. }
Success #stdin #stdout 0s 2288KB
stdin
Standard input is empty
stdout
Virtual filesystem root created: pfs_root

/ has 3 folders
Dir 1: /Folder 1
Dir 2: /Folder 2
Dir 3: /Folder 3

Folder 1 has 1 folders
Dir 4: /Folder 1/Folder 1-1

Folder 1-1 has 2 folders
Dir 5: /Folder 1/Folder 1-1/Folder 1-1-1
Dir 6: /Folder 1/Folder 1-1/Folder 1-1-2

Freeing /
Freeing Folder 3
Freeing Folder 2
Freeing Folder 1
Freeing Folder 1-1
Freeing Folder 1-1-2
Freeing Folder 1-1-1