Subversion Repositories HelenOS

Rev

Rev 3056 | Rev 3790 | Go to most recent revision | 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.     panic("Not reached\n");
  167.     return NULL;
  168. }
  169.  
  170. void sysinfo_set_item_val(const char *name, sysinfo_item_t **root, unative_t val)
  171. {
  172.     if (root == NULL)
  173.         root = &_root;
  174.    
  175.     /* If already created create only returns pointer
  176.        If not, create it */
  177.     sysinfo_item_t *item = sysinfo_create_path(name, root);
  178.    
  179.     if (item != NULL) { /* If in subsystem, unable to create or return so unable to set */
  180.         item->val.val = val;                  
  181.         item->val_type = SYSINFO_VAL_VAL;
  182.     }
  183. }
  184.  
  185. void sysinfo_set_item_function(const char *name, sysinfo_item_t **root, sysinfo_val_fn_t fn)
  186. {
  187.     if (root == NULL)
  188.         root = &_root;
  189.    
  190.     /* If already created create only returns pointer
  191.        If not, create it */
  192.     sysinfo_item_t *item = sysinfo_create_path(name, root);
  193.    
  194.     if (item != NULL) { /* If in subsystem, unable to create or return so  unable to set */
  195.         item->val.fn = fn;                  
  196.         item->val_type = SYSINFO_VAL_FUNCTION;
  197.     }
  198. }
  199.  
  200.  
  201. void sysinfo_set_item_undefined(const char *name, sysinfo_item_t **root)
  202. {
  203.     if (root == NULL)
  204.         root = &_root;
  205.    
  206.     /* If already created create only returns pointer
  207.        If not, create it */
  208.     sysinfo_item_t *item = sysinfo_create_path(name, root);
  209.    
  210.     if (item != NULL)
  211.         item->val_type = SYSINFO_VAL_UNDEFINED;
  212. }
  213.  
  214.  
  215. void sysinfo_dump(sysinfo_item_t **proot, int depth)
  216. {
  217.     sysinfo_item_t *root;
  218.     if (proot == NULL)
  219.         proot = &_root;
  220.    
  221.     root = *proot;
  222.    
  223.     while (root != NULL) {
  224.         int i;
  225.         unative_t val = 0;
  226.         char *vtype = NULL;
  227.        
  228.        
  229.         for (i = 0; i < depth; i++)
  230.             printf("  ");
  231.        
  232.         switch (root->val_type) {
  233.         case SYSINFO_VAL_UNDEFINED:
  234.             val = 0;
  235.             vtype = "UND";
  236.             break;
  237.         case SYSINFO_VAL_VAL:
  238.             val = root->val.val;
  239.             vtype = "VAL";
  240.             break;
  241.         case SYSINFO_VAL_FUNCTION:
  242.             val = ((sysinfo_val_fn_t) (root->val.fn)) (root);
  243.             vtype = "FUN";
  244.             break;
  245.         }
  246.        
  247.         printf("%s    %s val:%" PRIun "(%" PRIxn ") sub:%s\n", root->name, vtype, val,
  248.             val, (root->subinfo_type == SYSINFO_SUBINFO_NONE) ?
  249.             "NON" : ((root->subinfo_type == SYSINFO_SUBINFO_TABLE) ?
  250.             "TAB" : "FUN"));
  251.        
  252.         if (root->subinfo_type == SYSINFO_SUBINFO_TABLE)
  253.             sysinfo_dump(&(root -> subinfo.table), depth + 1);
  254.        
  255.         root = root->next;
  256.     }
  257. }
  258.  
  259. sysinfo_rettype_t sysinfo_get_val(const char *name, sysinfo_item_t **root)
  260. {
  261.     // TODO: Implement Subsystem subinfo (by function implemented subinfo)
  262.  
  263.     sysinfo_rettype_t ret = {0, false};
  264.  
  265.     if (root == NULL)
  266.         root = &_root;
  267.    
  268.     sysinfo_item_t *item = sysinfo_find_item(name, *root);
  269.    
  270.     if (item != NULL) {
  271.         if (item->val_type == SYSINFO_VAL_UNDEFINED)
  272.             return ret;
  273.         else
  274.             ret.valid = true;
  275.        
  276.         if (item->val_type == SYSINFO_VAL_VAL)
  277.             ret.val = item->val.val;
  278.         else
  279.             ret.val = ((sysinfo_val_fn_t) (item->val.fn)) (item);
  280.     }
  281.     return ret;
  282. }
  283.  
  284. #define SYSINFO_MAX_LEN 1024
  285.  
  286. unative_t sys_sysinfo_valid(unative_t ptr, unative_t len)
  287. {
  288.     char *str;
  289.     sysinfo_rettype_t ret = {0, 0};
  290.  
  291.     if (len > SYSINFO_MAX_LEN)
  292.         return ret.valid;
  293.     str = malloc(len + 1, 0);
  294.    
  295.     ASSERT(str);
  296.     if (!((copy_from_uspace(str, (void *) ptr, len + 1)) || (str[len])))
  297.         ret = sysinfo_get_val(str, NULL);
  298.    
  299.     free(str);
  300.     return ret.valid;
  301. }
  302.  
  303. unative_t sys_sysinfo_value(unative_t ptr, unative_t len)
  304. {
  305.     char *str;
  306.     sysinfo_rettype_t ret = {0, 0};
  307.    
  308.     if (len > SYSINFO_MAX_LEN)
  309.         return ret.val;
  310.     str = malloc(len + 1, 0);
  311.    
  312.     ASSERT(str);
  313.     if (!((copy_from_uspace(str, (void *) ptr, len + 1)) || (str[len])))
  314.         ret = sysinfo_get_val(str, NULL);
  315.    
  316.     free(str);
  317.     return ret.val;
  318. }
  319.  
  320. /** @}
  321.  */
  322.