#include <stdio.h>
#include <stdlib.h>
#include <rsbac/types.h>
#include <rsbac/aci_data_structures.h>
#include <rsbac/getname.h>
#include <rsbac/syscalls.h>
#include <rsbac/error.h>
#include <rsbac/helpers.h>

int main(int argc, char ** argv)
{
  enum rsbac_attribute_t attr_list[RSBAC_FD_NR_ATTRIBUTES] = RSBAC_FD_ATTR_LIST;
  enum rsbac_attribute_t attr_list_dev[RSBAC_DEV_NR_ATTRIBUTES] = RSBAC_DEV_ATTR_LIST;
  int res = 0;
  char tmp1[80],tmp2[120];
  int i,j,verbose=0;
  union rsbac_attribute_value_t value;
  enum rsbac_target_t target;
  enum rsbac_attribute_t attr;
  char * progname;
  int inherit = 0;
  
  progname = argv[0];
  if ((argc > 1) && (!strcmp("-v",argv[1])) )
    {
      verbose=1;
      argv++;
      argc--;
    }  
  
  if ((argc > 1) && (!strcmp("-e",argv[1])) )
    {
      inherit=1;
      argv++;
      argc--;
    }  
  
  if (argc > 3)
    {
      if(verbose)
        printf("%s: %i targets\n\n", progname, argc - 3);
      target = get_target_nr(argv[1]);
      attr = get_attribute_nr(argv[2]);
      for (i=1;i < (argc-2);i++)
        {
          if(verbose)
            printf("Processing %s %i, '%s', attribute %s(%i)\n", argv[1], i, argv[i+2], argv[2], attr);
          value.dummy = -1;
          res = rsbac_get_attr_n(target, argv[i+2], attr, &value, inherit);
          if(res)
            {
              if((res > -RSBAC_EPERM) || (res < -RSBAC_EDECISIONMISMATCH))
                fprintf(stderr, "error: %s\n", strerror(-res));
              else
                {
                  get_error_name(tmp1,res);
                  fprintf(stderr, "error: %s\n", tmp1);
                }
            }
          else
            switch (attr)
              {
                case A_log_array_low:
                case A_log_array_high:
                  printf("%s: Returned value: %s\n",
                         argv[i+2], u64tostrlog(tmp1,value.log_array_low));
                  break;
                case A_mac_trusted_for_user:
                  printf("%s: Returned value: %u\n",
                         argv[i+2], value.mac_trusted_for_user);
                  break;
                case A_ff_flags:
                  printf("%s: Returned value: %u\n",
                         argv[i+2], value.ff_flags);
                  break;
                default:
                  printf("%s: Returned value: %i\n",
                         argv[i+2], value.dummy);
              }
        }
    }
  else
    {
      printf("%s (RSBAC %s)\n***\n", argv[0], VERSION);
      printf("Use: %s [-v] [-e] target-type attribute file/dirname(s)\n", progname);
      printf("- -v = verbose, -e = show effective (maybe inherited) value, not real\n");
      printf("- target-type = FILE, DIR or DEV,\n");
      printf("- attribute (string) and returned value = see following lists:\n");
      printf("- FILE and DIR:\n");
      for (j=0;j<RSBAC_FD_NR_ATTRIBUTES;j++)
        {
          get_attribute_name(tmp1,attr_list[j]);
          get_attribute_param(tmp2,attr_list[j]);
          printf("%s \t%s\n",tmp1,tmp2);
        }
      printf("- DEV:\n");
      for (j=0;j<RSBAC_DEV_NR_ATTRIBUTES;j++)
        {
          get_attribute_name(tmp1,attr_list_dev[j]);
          get_attribute_param(tmp2,attr_list_dev[j]);
          printf("%s \t%s\n",tmp1,tmp2);
        }
    }
  return (res);
}
