?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. /* l_inc.c -- include paths list structure.
  2.  
  3.    This is free and unencumbered software released into the public domain.
  4.    For more information, please refer to <http://unlicense.org>. */
  5.  
  6. #include "defs.h"
  7.  
  8. #include <stdbool.h>
  9. #include <limits.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include "debug.h"
  14. #include "platform.h"
  15. #include "l_list.h"
  16. #include "l_inc.h"
  17.  
  18. void
  19.     include_path_entry_clear
  20.     (
  21.         struct include_path_entry_t *self
  22.     )
  23. {
  24.     list_entry_clear (&self->list_entry);
  25.     self->real = NULL;
  26.     self->base = NULL;
  27.     self->user = NULL;
  28. }
  29.  
  30. void
  31.     include_path_entry_free
  32.     (
  33.         struct include_path_entry_t *self
  34.     )
  35. {
  36.     list_entry_free (&self->list_entry);
  37.     if (self->real)
  38.         free (self->real);
  39.     if (self->base)
  40.         free (self->base);
  41.     if (self->user)
  42.         free (self->user);
  43.     include_path_entry_clear (self);
  44. }
  45.  
  46. void
  47.     include_paths_clear
  48.     (
  49.         struct include_paths_t *self
  50.     )
  51. {
  52.     list_clear (&self->list);
  53. }
  54.  
  55. bool
  56.     include_paths_add
  57.     (
  58.         struct include_paths_t *self,
  59.         const char *real,
  60.         const char *base,
  61.         const char *user,
  62.         struct include_path_entry_t **result
  63.     )
  64. {
  65.     bool ok;
  66.     struct include_path_entry_t *p;
  67.     char *p_real, *p_base, *p_user;
  68. #if DEBUG == 1
  69.     unsigned i;
  70. #endif  // DEBUG == 1
  71.  
  72.     ok = false;
  73.     p = (struct include_path_entry_t *) NULL;
  74.     p_real = (char *) NULL;
  75.     p_base = (char *) NULL;
  76.     p_user = (char *) NULL;
  77.  
  78.     if (!self || !real || !base || !user)
  79.     {
  80.         _DBG ("Bad arguments.");
  81.         goto _local_exit;
  82.     }
  83.  
  84.     p = malloc (sizeof (struct include_path_entry_t));
  85.     if (!p)
  86.     {
  87.         _perror ("malloc");
  88.         goto _local_exit;
  89.     }
  90.     p_real = strdup (real);
  91.     if (!p_real)
  92.     {
  93.         _perror ("strdup");
  94.         goto _local_exit;
  95.     }
  96.     p_base = strdup (base);
  97.     if (!p_base)
  98.     {
  99.         _perror ("strdup");
  100.         goto _local_exit;
  101.     }
  102.     p_user = strdup (user);
  103.     if (!p_user)
  104.     {
  105.         _perror ("strdup");
  106.         goto _local_exit;
  107.     }
  108.  
  109.     include_path_entry_clear (p);
  110.     p->real = p_real;
  111.     p->base = p_base;
  112.     p->user = p_user;
  113.  
  114. #if DEBUG == 1
  115.     i = self->list.count;
  116. #endif  // DEBUG == 1
  117.     list_add_entry (& self->list, & p->list_entry);
  118.  
  119.     _DBG_ ("Added new include path #%u:", i);
  120.     _DBG_ ("Include path #%u: user path = '%s'", i, p->user);
  121.     _DBG_ ("Include path #%u: base path = '%s'", i, p->base);
  122.     _DBG_ ("Include path #%u: real path = '%s'", i, p->real);
  123.  
  124.     ok = true;
  125.  
  126. _local_exit:
  127.     if (!ok)
  128.     {
  129.         if (p)
  130.         {
  131.             free (p);
  132.             p = (struct include_path_entry_t *) NULL;
  133.         }
  134.         if (p_real)
  135.             free (p_real);
  136.         if (p_base)
  137.             free (p_base);
  138.         if (p_user)
  139.             free (p_user);
  140.     }
  141.     if (result)
  142.         *result = p;
  143.     return !ok;
  144. }
  145.  
  146. bool
  147.     include_paths_find_real
  148.     (
  149.         struct include_paths_t *self,
  150.         const char *real,
  151.         struct include_path_entry_t **result
  152.     )
  153. {
  154.     bool ok;
  155.     struct include_path_entry_t *p;
  156.     unsigned i;
  157.  
  158.     ok = false;
  159.     p = (struct include_path_entry_t *) NULL;
  160.  
  161.     if (!self || !real)
  162.     {
  163.         _DBG ("Bad arguments.");
  164.         goto _local_exit;
  165.     }
  166.  
  167.     p = (struct include_path_entry_t *) self->list.first;
  168.     i = 0;
  169.     while (p)
  170.     {
  171.         if (!strcmp (p->real, real))
  172.         {
  173.             // Success
  174.             _DBG_ ("Found user path '%s' (real path '%s') at #%u.", p->user, p->real, i);
  175.             ok = true;
  176.             goto _local_exit;
  177.         }
  178.         p = (struct include_path_entry_t *) p->list_entry.next;
  179.         i++;
  180.     }
  181.  
  182.     // Fail
  183.     //p = (struct include_path_entry_t *) NULL;
  184.     _DBG_ ("Failed to find real path '%s'.", real);
  185.  
  186. _local_exit:
  187.     if (result)
  188.         *result = p;
  189.     return !ok;
  190. }
  191.  
  192. bool
  193.     include_paths_find_user
  194.     (
  195.         struct include_paths_t *self,
  196.         const char *user,
  197.         struct include_path_entry_t **result
  198.     )
  199. {
  200.     bool ok;
  201.     struct include_path_entry_t *p;
  202.     unsigned i;
  203.  
  204.     ok = false;
  205.     p = (struct include_path_entry_t *) NULL;
  206.  
  207.     if (!self || !user)
  208.     {
  209.         _DBG ("Bad arguments.");
  210.         goto _local_exit;
  211.     }
  212.  
  213.     p = (struct include_path_entry_t *) self->list.first;
  214.     i = 0;
  215.     while (p)
  216.     {
  217.         if (!strcmp (p->user, user))
  218.         {
  219.             // Success
  220.             _DBG_ ("Found user path '%s' (real path '%s') at #%u.", p->user, p->real, i);
  221.             ok = true;
  222.             goto _local_exit;
  223.         }
  224.         p = (struct include_path_entry_t *) p->list_entry.next;
  225.         i++;
  226.     }
  227.  
  228.     // Fail
  229.     //p = (struct include_paths_t *) NULL;
  230.     _DBG_ ("Failed to find user path '%s'.", user);
  231.  
  232. _local_exit:
  233.     if (result)
  234.         *result = p;
  235.     return !ok;
  236. }
  237.  
  238. bool
  239.     include_paths_add_with_check
  240.     (
  241.         struct include_paths_t *self,
  242.         const char *user,
  243.         const char *base_path_real,
  244.         struct include_path_entry_t **result
  245.     )
  246. {
  247.     bool ok;
  248.     char *real, *tmp;
  249.     unsigned len;
  250.  
  251.     ok = false;
  252.     real = NULL;
  253.  
  254.     if (!self || !user || !base_path_real)
  255.     {
  256.         _DBG ("Bad arguments.");
  257.         goto _local_exit;
  258.     }
  259.  
  260.     if (check_path_abs (user))
  261.     {
  262.         // absolute path
  263.         // first - check if it is already added
  264.         real = resolve_full_path (user);
  265.         if (!real)
  266.         {
  267.             // Fail
  268.             _perror ("resolve_full_path");
  269.             goto _local_exit;
  270.         }
  271.         if (include_paths_find_real (self, real, result))
  272.         {
  273.             if (include_paths_add (self, real, "", user, result))
  274.             {
  275.                 // Fail
  276.                 _perror ("include_paths_add");
  277.                 goto _local_exit;
  278.             }
  279.         }
  280.         // Success
  281.         ok = true;
  282.         //goto _local_exit;
  283.     }
  284.     else
  285.     {
  286.         // relative path
  287.         // first - check if it is already added
  288.         if (!include_paths_find_user (self, user, result))
  289.         {
  290.             // Success
  291.             ok = true;
  292.             //goto _local_exit;
  293.         }
  294.         else
  295.         {
  296.             len = strlen (base_path_real) + 1 + strlen (user) + 1;
  297.             tmp = malloc (len);
  298.             if (!tmp)
  299.             {
  300.                 // Fail
  301.                 _perror ("malloc");
  302.                 goto _local_exit;
  303.             }
  304.             snprintf (tmp, len, "%s" PATHSEPSTR "%s", base_path_real, user);
  305.             real = resolve_full_path (tmp);
  306.             free (tmp);
  307.             if (!real)
  308.             {
  309.                 // Fail
  310.                 _perror ("resolve_full_path");
  311.                 goto _local_exit;
  312.             }
  313.             // trying real path - we are lucky
  314.             if (check_path_exists (real))
  315.             {
  316.                 if (!include_paths_add (self, real, base_path_real, user, result))
  317.                 {
  318.                     // Success
  319.                     ok = true;
  320.                     goto _local_exit;
  321.                 }
  322.                 // Fail
  323.             }
  324.             // Fail
  325.             _DBG_ ("Failed to find user path '%s'.", user);
  326.             //goto _local_exit;
  327.         }
  328.     }
  329.     // Success or Fail
  330.  
  331. _local_exit:
  332.     if (real)
  333.         free (real);
  334.     if (!ok)
  335.         if (result)
  336.             *result = (struct include_path_entry_t *) NULL;
  337.     return !ok;
  338. }
  339.  
  340. // Returns "false" on success ("result" if presents is set to list entry).
  341. bool
  342.     include_paths_resolve_file
  343.     (
  344.         struct include_paths_t *self,
  345.         const char *user,
  346.         struct include_path_entry_t **result
  347.     )
  348. {
  349.     bool ok;
  350.     char *real;
  351.     struct include_path_entry_t *p;
  352.     unsigned len;
  353. #if DEBUG == 1
  354.     unsigned i;
  355. #endif  // DEBUG == 1
  356.  
  357.     ok = false;
  358.     real = (char *) NULL;
  359.     p = (struct include_path_entry_t *) NULL;
  360.  
  361.     if (!self || !user)
  362.     {
  363.         _DBG ("Bad arguments.");
  364.         goto _local_exit;
  365.     }
  366.  
  367.     len = PATH_MAX + 1 + strlen (user) + 1;
  368.     real = malloc (len);
  369.     if (!real)
  370.     {
  371.         // Fail
  372.         _perror ("malloc");
  373.         goto _local_exit;
  374.     }
  375.  
  376.     p = (struct include_path_entry_t *) self->list.first;
  377. #if DEBUG == 1
  378.     i = 0;
  379. #endif  // DEBUG == 1
  380.     while (p)
  381.     {
  382.         snprintf (real, len, "%s" PATHSEPSTR "%s", p->real, user);
  383.         _DBG_ ("Checking user file '%s' at path '%s'...", user, p->real);
  384.         if (check_file_exists (real))
  385.         {
  386.             // Success
  387. #if DEBUG == 1
  388.             _DBG_ ("Found user file '%s' (real file '%s') at #%u.", user, real, i);
  389. #endif  // DEBUG == 1
  390.             ok = true;
  391.             goto _local_exit;
  392.         }
  393.         else
  394.         {
  395.             _DBG_ ("User file '%s' not found, skipped.", user);
  396.         }
  397.         p = (struct include_path_entry_t *) p->list_entry.next;
  398. #if DEBUG == 1
  399.         i++;
  400. #endif  // DEBUG == 1
  401.     }
  402.  
  403.     // Fail
  404.     //p = (struct include_path_entry_t *) NULL;
  405.     _DBG_ ("User file '%s' not resolved.", user);
  406.  
  407. _local_exit:
  408.     if (real)
  409.         free (real);
  410.     if (result)
  411.         *result = p;
  412.     return !ok;
  413. }
  414.  
  415. #if DEBUG == 1
  416. void
  417.     _DBG_include_paths_dump
  418.     (
  419.         struct include_paths_t *self
  420.     )
  421. {
  422.     struct include_path_entry_t *p;
  423.     unsigned i;
  424.  
  425.     if (!self)
  426.     {
  427.         _DBG ("Bad arguments.");
  428.         return;
  429.     }
  430.  
  431.     p = (struct include_path_entry_t *) self->list.first;
  432.     if (p)
  433.     {
  434.         i = 0;
  435.         do
  436.         {
  437.             _DBG_ ("Include path #%u: user path = '%s'", i, ((struct include_path_entry_t *) p)->user);
  438.             _DBG_ ("Include path #%u: base path = '%s'", i, ((struct include_path_entry_t *) p)->base);
  439.             _DBG_ ("Include path #%u: real path = '%s'", i, ((struct include_path_entry_t *) p)->real);
  440.             p = (struct include_path_entry_t *) ((struct include_path_entry_t *) p)->list_entry.next;
  441.             i++;
  442.         }
  443.         while (p);
  444.     }
  445.     else
  446.         _DBG ("No include paths.");
  447. }
  448. #endif  // DEBUG == 1
  449.  
  450. void
  451.     include_paths_free
  452.     (
  453.         struct include_paths_t *self
  454.     )
  455. {
  456.     struct include_path_entry_t *p, *n;
  457.  
  458.     p = (struct include_path_entry_t *) self->list.first;
  459.     while (p)
  460.     {
  461.         n = (struct include_path_entry_t *) p->list_entry.next;
  462.         include_path_entry_free (p);
  463.         free (p);
  464.         p = n;
  465.     }
  466.     include_paths_clear (self);
  467. }
  468.