Subversion Repositories HelenOS

Rev

Rev 3225 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2006 Jakub Vana
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup generic
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #include <sysinfo/sysinfo.h>
  36. #include <mm/slab.h>
  37. #include <print.h>
  38. #include <syscall/copy.h>
  39.  
  40. sysinfo_item_t *_root = NULL;
  41.  
  42.  
  43. static sysinfo_item_t *sysinfo_find_item(const char *name, sysinfo_item_t *subtree)
  44. {
  45.     if (subtree == NULL)
  46.         return NULL;
  47.    
  48.     while (subtree != NULL) {
  49.         int i = 0;
  50.         char *a = (char *) name;
  51.         char *b = subtree->name;
  52.        
  53.         while ((a[i] == b[i]) && (b[i]))
  54.             i++;
  55.        
  56.         if ((!a[i]) && (!b[i]))  /* Last name in path matches */
  57.             return subtree;
  58.        
  59.         if ((a[i] == '.') && (!b[i])) { /* Middle name in path matches */
  60.             if (subtree->subinfo_type == SYSINFO_SUBINFO_TABLE)
  61.                 return sysinfo_find_item(a + i + 1, subtree->subinfo.table);
  62.            
  63.             //if (subtree->subinfo_type == SYSINFO_SUBINFO_FUNCTION) /* Subinfo managed by subsystem */
  64.             //  return NULL;
  65.            
  66.             return NULL; /* No subinfo */
  67.         }
  68.         /* No matches try next */
  69.         subtree = subtree->next;
  70.         i = 0;
  71.     }
  72.     return NULL;
  73. }
  74.  
  75. static sysinfo_item_t *sysinfo_create_path(const char *name, sysinfo_item_t **psubtree)
  76. {
  77.     sysinfo_item_t *subtree;
  78.     subtree = *psubtree;
  79.    
  80.     if (subtree == NULL) {
  81.         sysinfo_item_t *item = malloc(sizeof(sysinfo_item_t), 0);
  82.         int i = 0, j;
  83.            
  84.         ASSERT(item);
  85.         *psubtree = item;
  86.         item->next = NULL;
  87.         item->val_type = SYSINFO_VAL_UNDEFINED;
  88.         item->subinfo.table = NULL;
  89.  
  90.         while (name[i] && (name[i] != '.'))
  91.             i++;
  92.            
  93.         item->name = malloc(i, 0);
  94.         ASSERT(item->name);
  95.  
  96.         for (j = 0; j < i; j++)
  97.             item->name[j] = name[j];
  98.         item->name[j] = 0;
  99.            
  100.         if (name[i]) { /* =='.' */
  101.             item->subinfo_type = SYSINFO_SUBINFO_TABLE;
  102.             return sysinfo_create_path(name + i + 1, &(item->subinfo.table));
  103.         }
  104.         item->subinfo_type = SYSINFO_SUBINFO_NONE;
  105.         return item;
  106.     }
  107.  
  108.     while (subtree != NULL) {
  109.         int i = 0, j;
  110.         char *a = (char *) name;
  111.         char *b = subtree->name;
  112.        
  113.         while ((a[i] == b[i]) && (b[i]))
  114.             i++;
  115.        
  116.         if ((!a[i]) && (!b[i])) /* Last name in path matches */
  117.             return subtree;
  118.        
  119.         if ((a[i] == '.') && (!b[i])) { /* Middle name in path matches */
  120.             if (subtree->subinfo_type == SYSINFO_SUBINFO_TABLE)
  121.                 return sysinfo_create_path(a + i + 1, &(subtree->subinfo.table));
  122.            
  123.             if (subtree->subinfo_type == SYSINFO_SUBINFO_NONE) {
  124.                 subtree->subinfo_type = SYSINFO_SUBINFO_TABLE;
  125.                 return sysinfo_create_path(a + i + 1,&(subtree->subinfo.table));
  126.             }
  127.            
  128.             //if (subtree->subinfo_type == SYSINFO_SUBINFO_FUNCTION) /* Subinfo managed by subsystem */
  129.             //  return NULL;
  130.            
  131.             return NULL;
  132.         }
  133.         /* No matches try next or create new*/
  134.         if (subtree->next == NULL) {
  135.             sysinfo_item_t *item = malloc(sizeof(sysinfo_item_t), 0);
  136.            
  137.             ASSERT(item);
  138.             subtree->next = item;
  139.             item->next = NULL;
  140.             item->val_type = SYSINFO_VAL_UNDEFINED;
  141.             item->subinfo.table = NULL;
  142.  
  143.             i = 0;
  144.             while (name[i] && (name[i] != '.'))
  145.                 i++;
  146.  
  147.             item->name = malloc(i, 0);
  148.             ASSERT(item->name);
  149.            
  150.             for (j = 0; j < i; j++)
  151.                 item->name[j] = name[j];
  152.            
  153.             item->name[j] = 0;
  154.  
  155.             if(name[i]) { /* =='.' */
  156.                 item->subinfo_type = SYSINFO_SUBINFO_TABLE;
  157.                 return sysinfo_create_path(name + i + 1, &(item->subinfo.table));
  158.             }
  159.             item->subinfo_type = SYSINFO_SUBINFO_NONE;
  160.             return item;
  161.         } else {
  162.             subtree = subtree->next;
  163.             i = 0;
  164.         }  
  165.     }
  166.  
  167.     panic("Not reached.");
  168.     return NULL;
  169. }
  170.  
  171. void sysinfo_set_item_val(const char *name, sysinfo_item_t **root, unative_t val)
  172. {
  173.     if (root == NULL)
  174.         root = &_root;
  175.    
  176.     /* If already created create only returns pointer
  177.        If not, create it */
  178.     sysinfo_item_t *item = sysinfo_create_path(name, root);
  179.    
  180.     if (item != NULL) { /* If in subsystem, unable to create or return so unable to set */
  181.         item->val.val = val;                  
  182.         item->val_type = SYSINFO_VAL_VAL;
  183.     }
  184. }
  185.  
  186. void sysinfo_set_item_function(const char *name, sysinfo_item_t **root, sysinfo_val_fn_t fn)
  187. {
  188.     if (root == NULL)
  189.         root = &_root;
  190.    
  191.     /* If already created create only returns pointer
  192.        If not, create it */
  193.     sysinfo_item_t *item = sysinfo_create_path(name, root);
  194.    
  195.     if (item != NULL) { /* If in subsystem, unable to create or return so  unable to set */
  196.         item->val.fn = fn;                  
  197.         item->val_type = SYSINFO_VAL_FUNCTION;
  198.     }
  199. }
  200.  
  201.  
  202. void sysinfo_set_item_undefined(const char *name, sysinfo_item_t **root)
  203. {
  204.     if (root == NULL)
  205.         root = &_root;
  206.    
  207.     /* If already created create only returns pointer
  208.        If not, create it */
  209.     sysinfo_item_t *item = sysinfo_create_path(name, root);
  210.    
  211.     if (item != NULL)
  212.         item->val_type = SYSINFO_VAL_UNDEFINED;
  213. }
  214.  
  215.  
  216. void sysinfo_dump(sysinfo_item_t **proot, int depth)
  217. {
  218.     sysinfo_item_t *root;
  219.     if (proot == NULL)
  220.         proot = &_root;
  221.    
  222.     root = *proot;
  223.    
  224.     while (root != NULL) {
  225.         int i;
  226.         unative_t val = 0;
  227.         char *vtype = NULL;
  228.        
  229.        
  230.         for (i = 0; i < depth; i++)
  231.             printf("  ");
  232.        
  233.         switch (root->val_type) {
  234.         case SYSINFO_VAL_UNDEFINED:
  235.             val = 0;
  236.             vtype = "UND";
  237.             break;
  238.         case SYSINFO_VAL_VAL:
  239.             val = root->val.val;
  240.             vtype = "VAL";
  241.             break;
  242.         case SYSINFO_VAL_FUNCTION:
  243.             val = ((sysinfo_val_fn_t) (root->val.fn)) (root);
  244.             vtype = "FUN";
  245.             break;
  246.         }
  247.        
  248.         printf("%s    %s val:%" PRIun "(%" PRIxn ") sub:%s\n", root->name, vtype, val,
  249.             val, (root->subinfo_type == SYSINFO_SUBINFO_NONE) ?
  250.             "NON" : ((root->subinfo_type == SYSINFO_SUBINFO_TABLE) ?
  251.             "TAB" : "FUN"));
  252.        
  253.         if (root->subinfo_type == SYSINFO_SUBINFO_TABLE)
  254.             sysinfo_dump(&(root -> subinfo.table), depth + 1);
  255.        
  256.         root = root->next;
  257.     }
  258. }
  259.  
  260. sysinfo_rettype_t sysinfo_get_val(const char *name, sysinfo_item_t **root)
  261. {
  262.     // TODO: Implement Subsystem subinfo (by function implemented subinfo)
  263.  
  264.     sysinfo_rettype_t ret = {0, false};
  265.  
  266.     if (root == NULL)
  267.         root = &_root;
  268.    
  269.     sysinfo_item_t *item = sysinfo_find_item(name, *root);
  270.    
  271.     if (item != NULL) {
  272.         if (item->val_type == SYSINFO_VAL_UNDEFINED)
  273.             return ret;
  274.         else
  275.             ret.valid = true;
  276.        
  277.         if (item->val_type == SYSINFO_VAL_VAL)
  278.             ret.val = item->val.val;
  279.         else
  280.             ret.val = ((sysinfo_val_fn_t) (item->val.fn)) (item);
  281.     }
  282.     return ret;
  283. }
  284.  
  285. #define SYSINFO_MAX_LEN 1024
  286.  
  287. unative_t sys_sysinfo_valid(unative_t ptr, unative_t len)
  288. {
  289.     char *str;
  290.     sysinfo_rettype_t ret = {0, 0};
  291.  
  292.     if (len > SYSINFO_MAX_LEN)
  293.         return ret.valid;
  294.     str = malloc(len + 1, 0);
  295.    
  296.     ASSERT(str);
  297.     if (!((copy_from_uspace(str, (void *) ptr, len + 1)) || (str[len])))
  298.         ret = sysinfo_get_val(str, NULL);
  299.    
  300.     free(str);
  301.     return ret.valid;
  302. }
  303.  
  304. unative_t sys_sysinfo_value(unative_t ptr, unative_t len)
  305. {
  306.     char *str;
  307.     sysinfo_rettype_t ret = {0, 0};
  308.    
  309.     if (len > SYSINFO_MAX_LEN)
  310.         return ret.val;
  311.     str = malloc(len + 1, 0);
  312.    
  313.     ASSERT(str);
  314.     if (!((copy_from_uspace(str, (void *) ptr, len + 1)) || (str[len])))
  315.         ret = sysinfo_get_val(str, NULL);
  316.    
  317.     free(str);
  318.     return ret.val;
  319. }
  320.  
  321. /** @}
  322.  */
  323.