?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. /* l_isrc.c - input sources 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_isrc.h"
  17.  
  18. void
  19.     input_source_entry_clear
  20.     (
  21.         struct input_source_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.     input_source_entry_free
  32.     (
  33.         struct input_source_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.     input_source_entry_clear (self);
  44. }
  45.  
  46. void
  47.     input_sources_clear
  48.     (
  49.         struct input_sources_t *self
  50.     )
  51. {
  52.     list_clear (&self->list);
  53. }
  54.  
  55. bool
  56.     input_sources_add
  57.     (
  58.         struct input_sources_t *self,
  59.         const char *real,
  60.         const char *base,
  61.         const char *user,
  62.         struct input_source_entry_t **result
  63.     )
  64. {
  65.     bool ok;
  66.     struct input_source_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 input_source_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 input_source_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.     input_source_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 ((struct list_t *) self, (struct list_entry_t *) p);
  118.  
  119.     _DBG_ ("Added new input source #%u:", i);
  120.     _DBG_ ("Input source #%u: user file = '%s'", i, p->user);
  121.     _DBG_ ("Input source #%u: base path = '%s'", i, p->base);
  122.     _DBG_ ("Input source #%u: real file = '%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 input_source_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.     input_sources_find_real
  148.     (
  149.         struct input_sources_t *self,
  150.         const char *real,
  151.         struct input_source_entry_t **result
  152.     )
  153. {
  154.     bool ok;
  155.     struct input_source_entry_t *p;
  156.     unsigned i;
  157.  
  158.     ok = false;
  159.     p = (struct input_source_entry_t *) NULL;
  160.  
  161.     if (!self || !real)
  162.     {
  163.         _DBG ("Bad arguments.");
  164.         goto _local_exit;
  165.     }
  166.  
  167.     p = (struct input_source_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 file '%s' (real file '%s') at #%u.", p->user, p->real, i);
  175.             ok = true;
  176.             goto _local_exit;
  177.         }
  178.         p = (struct input_source_entry_t *) p->list_entry.next;
  179.         i++;
  180.     }
  181.  
  182.     // Fail
  183.     //p = (struct input_source_entry_t *) NULL;
  184.     _DBG_ ("Failed to find real file '%s'.", real);
  185.  
  186. _local_exit:
  187.     if (result)
  188.         *result = p;
  189.     return !ok;
  190. }
  191.  
  192. bool
  193.     input_sources_find_user
  194.     (
  195.         struct input_sources_t *self,
  196.         const char *user,
  197.         struct input_source_entry_t **result
  198.     )
  199. {
  200.     bool ok;
  201.     struct input_source_entry_t *p;
  202.     unsigned i;
  203.  
  204.     ok = false;
  205.     p = (struct input_source_entry_t *) NULL;
  206.  
  207.     if (!self || !user)
  208.     {
  209.         _DBG ("Bad arguments.");
  210.         goto _local_exit;
  211.     }
  212.  
  213.     p = (struct input_source_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 file '%s' (real file '%s') at #%u.", p->user, p->real, i);
  221.             ok = true;
  222.             goto _local_exit;
  223.         }
  224.         p = (struct input_source_entry_t *) p->list_entry.next;
  225.         i++;
  226.     }
  227.  
  228.     // Fail
  229.     //p = (struct input_source_entry_t *) NULL;
  230.     _DBG_ ("Failed to find user file '%s'.", user);
  231.  
  232. _local_exit:
  233.     if (result)
  234.         *result = p;
  235.     return !ok;
  236. }
  237.  
  238. bool
  239.     input_sources_add_with_check
  240.     (
  241.         struct input_sources_t *self,
  242.         const char *user,
  243.         const char *base_path_real,
  244.         struct input_source_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 (input_sources_find_real (self, real, result))
  272.         {
  273.             if (input_sources_add (self, real, "", user, result))
  274.             {
  275.                 // Fail
  276.                 goto _local_exit;
  277.             }
  278.             // Success
  279.             //ok = true;
  280.             //goto _local_exit;
  281.         }
  282.         // Success
  283.         ok = true;
  284.         //goto _local_exit;
  285.     }
  286.     else
  287.     {
  288.         // relative path
  289.         // first - check if it is already added
  290.         if (!input_sources_find_user (self, user, result))
  291.         {
  292.             // Success
  293.             ok = true;
  294.             //goto _local_exit;
  295.         }
  296.         else
  297.         {
  298.             len = strlen (base_path_real) + 1 + strlen (user) + 1;
  299.             tmp = malloc (len);
  300.             if (!tmp)
  301.             {
  302.                 // Fail
  303.                 _perror ("malloc");
  304.                 goto _local_exit;
  305.             }
  306.             snprintf (tmp, len, "%s" PATHSEPSTR "%s", base_path_real, user);
  307.             real = resolve_full_path (tmp);
  308.             free (tmp);
  309.             if (!real)
  310.             {
  311.                 // Fail
  312.                 _perror ("resolve_full_path");
  313.                 goto _local_exit;
  314.             }
  315.             // trying real path - we are lucky
  316.             if (check_file_exists (real))
  317.             {
  318.                 if (!input_sources_add (self, real, base_path_real, user, result))
  319.                 {
  320.                     // Success
  321.                     ok = true;
  322.                     //goto _local_exit;
  323.                 }
  324.                 // Fail
  325.                 //goto _local_exit;
  326.             }
  327.             else
  328.             {
  329.                 // Fail
  330.                 _DBG_ ("Failed to find user file '%s'.", user);
  331.                 //goto _local_exit;
  332.             }
  333.         }
  334.     }
  335.  
  336. _local_exit:
  337.     if (real)
  338.         free (real);
  339.     if (!ok)
  340.         if (result)
  341.             *result = NULL;
  342.     return !ok;
  343. }
  344.  
  345. #if DEBUG == 1
  346. void
  347.     _DBG_input_sources_dump
  348.     (
  349.         struct input_sources_t *self
  350.     )
  351. {
  352.     void *p;
  353.     unsigned i;
  354.  
  355.     if (!self)
  356.     {
  357.         _DBG ("Bad arguments.");
  358.         return;
  359.     }
  360.  
  361.     p = (struct input_source_entry_t *) self->list.first;
  362.     if (p)
  363.     {
  364.         i = 0;
  365.         do
  366.         {
  367.             _DBG_ ("Input source #%u: user file = '%s'", i, ((struct input_source_entry_t *) p)->user);
  368.             _DBG_ ("Input source #%u: base path = '%s'", i, ((struct input_source_entry_t *) p)->base);
  369.             _DBG_ ("Input source #%u: real file = '%s'", i, ((struct input_source_entry_t *) p)->real);
  370.             p = (struct input_source_entry_t *) ((struct input_source_entry_t *) p)->list_entry.next;
  371.             i++;
  372.         }
  373.         while (p);
  374.     }
  375.     else
  376.         _DBG ("No input sources.");
  377. }
  378. #endif  // DEBUG == 1
  379.  
  380. void
  381.     input_sources_free
  382.     (
  383.         struct input_sources_t *self
  384.     )
  385. {
  386.     struct input_source_entry_t *p, *n;
  387.  
  388.     p = (struct input_source_entry_t *) self->list.first;
  389.     while (p)
  390.     {
  391.         n = (struct input_source_entry_t *) p->list_entry.next;
  392.         input_source_entry_free (p);
  393.         free (p);
  394.         p = n;
  395.     }
  396.     input_sources_clear (self);
  397. }
  398.