#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;
  int verbose=0;
  union rsbac_attribute_value_t value;
  enum rsbac_target_t target;
  enum rsbac_attribute_t attr;
  char * progname;
  
  progname = argv[0];
  if ((argc > 1) && (!strcmp("-v",argv[1])) )
    {
      verbose=1;
      argv++;
      argc--;
    }  
  if (argc > 4)
    {
      if(verbose)
        printf("%s: %i targets\n\n", progname, argc - 4);
      target = get_target_nr(argv[1]);
      attr = get_attribute_nr(argv[2]);
      switch(attr)
        {
          case A_none:
            fprintf(stderr, "%s: Invalid attribute %s\n", argv[0], argv[3]);
            exit(1);
          case A_log_array_low:
          case A_log_array_high:
            if(strlen(argv[3]) != R_NONE)
              {
                fprintf(stderr, "%s: Invalid attribute value, length must be %i\n", argv[0], R_NONE);
                exit(1);
              }
            for(j=0;j<strlen(argv[3]);j++)
              {
                if(   argv[3][j] != '0'
                   && argv[3][j] != '1')
                  {
                    fprintf(stderr, "%s: Invalid attribute value char, must be 0 or 1\n", argv[0]);
                    exit(1);
                  }
              }
            strtou64log(argv[3], &value.log_array_low);
            break;

          case A_mac_trusted_for_user:
            value.mac_trusted_for_user = strtol(argv[3],0,0);

          default:
            value.dummy = strtol(argv[3],0,0);
        }
      for (i=1;i < (argc-3);i++)
        {
          if(verbose)
            printf("Processing %s %i, '%s', attribute %s(%i), value %i\n", argv[1], i, argv[i+3], argv[2], attr, value.dummy);
          res = rsbac_set_attr_n(target, argv[i+3], attr, &value);
          if(res)
            {
              if((res > -RSBAC_EPERM) || (res < -RSBAC_EDECISIONMISMATCH))
                fprintf(stderr, "%s: error: %s\n", argv[i+3], strerror(-res));
              else
                {
                  get_error_name(tmp1,res);
                  fprintf(stderr, "%s: error: %s\n", argv[i+3], tmp1);
                }
            }
        }
    }
  else
    {
      printf("%s (RSBAC %s)\n***\n", argv[0], VERSION);
      printf("Use: %s [-v] target-type attribute value file/dirname(s)\n", progname);  
      printf("- -v = verbose, target-type = FILE, DIR or DEV,\n");
      printf("- attribute (string) and value (integer) = see following list:\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);
}

