#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 j;
  union rsbac_attribute_value_t value,value2;
  enum rsbac_target_t target;
  enum rsbac_attribute_t attr;
  enum rsbac_adf_request_t request;
  enum rsbac_log_level_t   log_level;
  int inherit = 0;
  char * progname = argv[0];
  
  if ((argc > 1) && (!strcmp("-e",argv[1])) )
    {
      inherit=1;
      argv++;
      argc--;
    }  
  
  if (argc == 4)
    {
      target = get_target_nr(argv[1]);
      attr = get_attribute_nr(argv[3]);
      value.dummy = -1;
      res = rsbac_get_attr_n(target, argv[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);
            }
          exit(1);
        }
      else
        {
          switch (attr)
            {
              case A_log_array_low:
              case A_log_array_high:
                printf("%s\n",u64tostrlog(tmp1,value.log_array_low));
                break;
              case A_mac_trusted_for_user:
                printf("%u\n",value.mac_trusted_for_user);
                break;
              case A_ff_flags:
                printf("%u\n",value.ff_flags);
                break;
              default:
                printf("%i\n",value.dummy);
            }
          exit(0);
        }
    }
  else
    if (   argc == 5
        && !strcmp(argv[3],"log_level"))
      {
        target = get_target_nr(argv[1]);
        request = get_request_nr(argv[4]);
        if(request == R_NONE)
          {
            fprintf(stderr, "Invalid request type %s\n", argv[4]);
            printf("Valid request types:\n");
            for(j=0;j<R_NONE;j++)
              {
                printf("%s\n", get_request_name(tmp1,j));
              }
            exit(1);
          }
        res = rsbac_get_attr_n(target, argv[2], A_log_array_low, &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);
              }
            exit(1);
          }
        res = rsbac_get_attr_n(target, argv[2], A_log_array_high, &value2, 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);
              }
            exit(1);
          }
        log_level =     ((value.log_array_low   >> request) & 1)
                    | ( ((value2.log_array_high >> request) & 1) << 1);
        printf("%i\n",log_level);
        exit(0);
      }
    else
      {
        printf("%s (RSBAC %s)\n***\n", progname, VERSION);
        printf("Use: %s target-type file/dirname attribute [request]\n", progname);  
        printf("- -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 list:\n");
        printf("- FILE and DIR:\n");
        printf("log_level\t\t(additional parameter request-type)\n\t\t\t0=none, 1=denied, 2=full, 3=request based\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");
        printf("log_level\t\t(additional parameter request-type)\n\t\t\t0=none, 1=denied, 2=full, 3=request based\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);
          }
      }
  exit(1);
}
