Switch to unified view

a/pxattr.cpp b/pxattr.cpp
1
/* @(#$Id: pxattr.cpp,v 1.9 2009-01-20 13:48:34 dockes Exp $  (C) 2009 J.F.Dockes
1
/*
2
Copyright (c) 2009 Jean-Francois Dockes
2
Copyright (c) 2009 Jean-Francois Dockes
3
3
4
Permission is hereby granted, free of charge, to any person
4
Permission is hereby granted, free of charge, to any person
5
obtaining a copy of this software and associated documentation
5
obtaining a copy of this software and associated documentation
6
files (the "Software"), to deal in the Software without
6
files (the "Software"), to deal in the Software without
...
...
20
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
OTHER DEALINGS IN THE SOFTWARE.
23
OTHER DEALINGS IN THE SOFTWARE.
24
*/
24
*/
25
26
/** \file pxattr.cpp 
27
    \brief This is a comment for file pxattr.cpp 
28
 */
25
29
26
// We want this to compile even to empty on non-supported systems. makes
30
// We want this to compile even to empty on non-supported systems. makes
27
// things easier for autoconf
31
// things easier for autoconf
28
#if defined(__FreeBSD__) || defined(__gnu_linux__) || defined(__APPLE__)
32
#if defined(__FreeBSD__) || defined(__gnu_linux__) || defined(__APPLE__)
29
33
...
...
487
#include <string>
491
#include <string>
488
using namespace std;
492
using namespace std;
489
493
490
#include "pxattr.h"
494
#include "pxattr.h"
491
495
492
static void dotests()
496
static void dotests();
493
{
494
    static const char *tfn = "pxattr_testtmp.xyz";
495
    static const char *NAMES[] = {"ORG.PXATTR.NAME1", "ORG.PXATTR.N2", 
496
                "ORG.PXATTR.LONGGGGGGGGisSSSHHHHHHHHHNAME3"};
497
    static const char *VALUES[] = {"VALUE1", "VALUE2", "VALUE3"};
498
    static bool verbose = true;
499
500
    /* Create test file if it doesn't exist, remove all attributes */
501
    int fd = open(tfn, O_RDWR|O_CREAT, 0755);
502
    if (fd < 0) {
503
  perror("open/create");
504
  exit(1);
505
    }
506
507
508
    if (verbose)
509
  fprintf(stdout, "Cleanup old attrs\n");
510
    vector<string> names;
511
    if (!pxattr::list(tfn, &names)) {
512
  perror("pxattr::list");
513
  exit(1);
514
    }
515
    for (vector<string>::const_iterator it = names.begin(); 
516
   it != names.end(); it++) {
517
  string value;
518
  if (!pxattr::del(fd, *it)) {
519
      perror("pxattr::del");
520
      exit(1);
521
  }
522
    }
523
    /* Check that there are no attributes left */
524
    names.clear();
525
    if (!pxattr::list(tfn, &names)) {
526
  perror("pxattr::list");
527
  exit(1);
528
    }
529
    if (names.size() != 0) {
530
  fprintf(stderr, "Attributes remain after initial cleanup !\n");
531
  for (vector<string>::const_iterator it = names.begin();
532
       it != names.end(); it++) {
533
      fprintf(stderr, "%s\n", (*it).c_str());
534
  }
535
  exit(1);
536
    }
537
538
    /* Create attributes, check existence and value */
539
    if (verbose)
540
  fprintf(stdout, "Creating extended attributes\n");
541
    for (int i = 0; i < 3; i++) {
542
  if (!pxattr::set(fd, NAMES[i], VALUES[i])) {
543
      perror("pxattr::set");
544
      exit(1);
545
  }
546
    }
547
    if (verbose)
548
  fprintf(stdout, "Checking creation\n");
549
    for (int i = 0; i < 3; i++) {
550
  string value;
551
  if (!pxattr::get(tfn, NAMES[i], &value)) {
552
      perror("pxattr::get");
553
      exit(1);
554
  }
555
  if (value.compare(VALUES[i])) {
556
      fprintf(stderr, "Wrong value after create !\n");
557
      exit(1);
558
  }
559
    }
560
561
    /* Delete one, check list */
562
    if (verbose)
563
  fprintf(stdout, "Delete one\n");
564
    if (!pxattr::del(tfn, NAMES[1])) {
565
  perror("pxattr::del one name");
566
  exit(1);
567
    }
568
    if (verbose)
569
  fprintf(stdout, "Check list\n");
570
    for (int i = 0; i < 3; i++) {
571
  string value;
572
  if (!pxattr::get(fd, NAMES[i], &value)) {
573
      if (i == 1)
574
      continue;
575
      perror("pxattr::get");
576
      exit(1);
577
  } else if (i == 1) {
578
      fprintf(stderr, "Name at index 1 still exists after deletion\n");
579
      exit(1);
580
  }
581
  if (value.compare(VALUES[i])) {
582
      fprintf(stderr, "Wrong value after delete 1 !\n");
583
      exit(1);
584
  }
585
    }
586
587
    /* Test the CREATE/REPLACE flags */
588
    // Set existing with flag CREATE should fail
589
    if (verbose)
590
  fprintf(stdout, "Testing CREATE/REPLACE flags use\n");
591
    if (pxattr::set(tfn, NAMES[0], VALUES[0], pxattr::PXATTR_CREATE)) {
592
  fprintf(stderr, "Create existing with flag CREATE succeeded !\n");
593
  exit(1);
594
    }
595
    // Set new with flag REPLACE should fail
596
    if (pxattr::set(tfn, NAMES[1], VALUES[1], pxattr::PXATTR_REPLACE)) {
597
  fprintf(stderr, "Create new with flag REPLACE succeeded !\n");
598
  exit(1);
599
    }
600
    // Set new with flag CREATE should succeed
601
    if (!pxattr::set(fd, NAMES[1], VALUES[1], pxattr::PXATTR_CREATE)) {
602
  fprintf(stderr, "Create new with flag CREATE failed !\n");
603
  exit(1);
604
    }
605
    // Set existing with flag REPLACE should succeed
606
    if (!pxattr::set(fd, NAMES[0], VALUES[0], pxattr::PXATTR_REPLACE)) {
607
  fprintf(stderr, "Create existing with flag REPLACE failed !\n");
608
  exit(1);
609
    }
610
    close(fd);
611
    unlink(tfn);
612
    exit(0);
613
}
614
497
615
// \-quote character c in input \ -> \\, nl -> \n cr -> \rc -> \c
498
// \-quote character c in input \ -> \\, nl -> \n cr -> \rc -> \c
616
static void quote(const string& in, string& out, int c)
499
static void quote(const string& in, string& out, int c)
617
{
500
{
618
    out.clear();
501
    out.clear();
...
...
936
    } 
819
    } 
937
820
938
    exit(0);
821
    exit(0);
939
}
822
}
940
823
824
static void fatal(const string& s)
825
{
826
    perror(s.c_str());
827
    exit(1);
828
}
941
829
830
static bool testbackups()
831
{
832
    static const char *top = "ttop";
833
    static const char *d1 = "d1";
834
    static const char *d2 = "d2";
835
    static const char *tfn1 = "tpxattr1.txt";
836
    static const char *tfn2 = "tpxattr2.txt";
837
    static const char *dump = "attrdump.txt";
838
    static const char *NAMES[] = {"ORG.PXATTR.NAME1", 
839
                "ORG=PXATTR\"=\\=\n", 
840
                "=", "Name4"};
841
    static const char *VALUES[] = 
842
  {"VALUE1", "VALUE2", "VALUE3=VALUE3equal",
843
   "VALUE4\n is more like"
844
   " normal text\n with new lines and \"\\\" \\\" backslashes"};
845
846
    static const int nattrs = sizeof(NAMES) / sizeof(char *);
847
848
    if (mkdir(top, 0777))
849
  fatal("Cant mkdir ttop");
850
    if (chdir(top))
851
  fatal("cant chdir ttop");
852
    if (mkdir(d1, 0777) || mkdir(d2, 0777))
853
  fatal("Can't mkdir ttdop/dx\n");
854
    if (chdir(d1))
855
  fatal("chdir d1");
856
857
    int fd;
858
    if ((fd = open(tfn1, O_RDWR|O_CREAT, 0755)) < 0)
859
  fatal("create d1/tpxattr1.txt");
860
    /* Set attrs */
861
    for (int i = 0; i < nattrs; i++) {
862
  if (!pxattr::set(fd, NAMES[i], VALUES[i]))
863
      fatal("pxattr::set");
864
    }
865
    close(fd);
866
    if ((fd = open(tfn2, O_RDWR|O_CREAT, 0755)) < 0)
867
  fatal("create d1/tpxattr2.txt");
868
    /* Set attrs */
869
    for (int i = 0; i < nattrs; i++) {
870
  if (!pxattr::set(fd, NAMES[i], VALUES[i]))
871
      fatal("pxattr::set");
872
    }
873
    close(fd);
874
875
    /* Create dump */
876
    string cmd;
877
    cmd = string("pxattr -lR . > " ) + dump;
878
    if (system(cmd.c_str()))
879
  fatal(cmd + " in d1");
880
    if (chdir("../d2"))
881
  fatal("chdir ../d2");
882
    if (close(open(tfn1, O_RDWR|O_CREAT, 0755)))
883
  fatal("create d2/tpxattr.txt");
884
    if (close(open(tfn2, O_RDWR|O_CREAT, 0755)))
885
  fatal("create d2/tpxattr.txt");
886
    cmd = string("pxattr -S ../d1/" ) + dump;
887
    if (system(cmd.c_str()))
888
  fatal(cmd);
889
    cmd = string("pxattr -lR . > " ) + dump;
890
    if (system(cmd.c_str()))
891
  fatal(cmd + " in d2");
892
    cmd = string("diff ../d1/") + dump + " " + dump;
893
    if (system(cmd.c_str()))
894
  fatal(cmd);
895
    cmd = string("cat ") + dump;
896
    system(cmd.c_str());
897
898
    if (1) {
899
  unlink(dump);
900
  unlink(tfn1);
901
  unlink(tfn2);
902
  if (chdir("../d1"))
903
      fatal("chdir ../d1");
904
  unlink(dump);
905
  unlink(tfn1);
906
  unlink(tfn2);
907
  if (chdir("../"))
908
      fatal("chdir .. 1");
909
  if (rmdir(d1))
910
      fatal("rmdir d1");
911
  if (rmdir(d2))
912
      fatal("rmdir d2");
913
  if (chdir("../"))
914
      fatal("chdir .. 2");
915
  if (rmdir(top))
916
      fatal("rmdir ttop");
917
    }
918
    return true;
919
}
920
921
static void dotests()
922
{
923
    static const char *tfn = "pxattr_testtmp.xyz";
924
    static const char *NAMES[] = {"ORG.PXATTR.NAME1", "ORG.PXATTR.N2", 
925
                "ORG.PXATTR.LONGGGGGGGGisSSSHHHHHHHHHNAME3"};
926
    static const char *VALUES[] = {"VALUE1", "VALUE2", "VALUE3"};
927
    static bool verbose = true;
928
929
    /* Create test file if it doesn't exist, remove all attributes */
930
    int fd = open(tfn, O_RDWR|O_CREAT, 0755);
931
    if (fd < 0) {
932
  perror("open/create");
933
  exit(1);
934
    }
935
936
    if (verbose)
937
  fprintf(stdout, "Cleanup old attrs\n");
938
    vector<string> names;
939
    if (!pxattr::list(tfn, &names)) {
940
  perror("pxattr::list");
941
  exit(1);
942
    }
943
    for (vector<string>::const_iterator it = names.begin(); 
944
   it != names.end(); it++) {
945
  string value;
946
  if (!pxattr::del(fd, *it)) {
947
      perror("pxattr::del");
948
      exit(1);
949
  }
950
    }
951
    /* Check that there are no attributes left */
952
    names.clear();
953
    if (!pxattr::list(tfn, &names)) {
954
  perror("pxattr::list");
955
  exit(1);
956
    }
957
    if (names.size() != 0) {
958
  fprintf(stderr, "Attributes remain after initial cleanup !\n");
959
  for (vector<string>::const_iterator it = names.begin();
960
       it != names.end(); it++) {
961
      fprintf(stderr, "%s\n", (*it).c_str());
962
  }
963
  exit(1);
964
    }
965
966
    /* Create attributes, check existence and value */
967
    if (verbose)
968
  fprintf(stdout, "Creating extended attributes\n");
969
    for (int i = 0; i < 3; i++) {
970
  if (!pxattr::set(fd, NAMES[i], VALUES[i])) {
971
      perror("pxattr::set");
972
      exit(1);
973
  }
974
    }
975
    if (verbose)
976
  fprintf(stdout, "Checking creation\n");
977
    for (int i = 0; i < 3; i++) {
978
  string value;
979
  if (!pxattr::get(tfn, NAMES[i], &value)) {
980
      perror("pxattr::get");
981
      exit(1);
982
  }
983
  if (value.compare(VALUES[i])) {
984
      fprintf(stderr, "Wrong value after create !\n");
985
      exit(1);
986
  }
987
    }
988
989
    /* Delete one, check list */
990
    if (verbose)
991
  fprintf(stdout, "Delete one\n");
992
    if (!pxattr::del(tfn, NAMES[1])) {
993
  perror("pxattr::del one name");
994
  exit(1);
995
    }
996
    if (verbose)
997
  fprintf(stdout, "Check list\n");
998
    for (int i = 0; i < 3; i++) {
999
  string value;
1000
  if (!pxattr::get(fd, NAMES[i], &value)) {
1001
      if (i == 1)
1002
      continue;
1003
      perror("pxattr::get");
1004
      exit(1);
1005
  } else if (i == 1) {
1006
      fprintf(stderr, "Name at index 1 still exists after deletion\n");
1007
      exit(1);
1008
  }
1009
  if (value.compare(VALUES[i])) {
1010
      fprintf(stderr, "Wrong value after delete 1 !\n");
1011
      exit(1);
1012
  }
1013
    }
1014
1015
    /* Test the CREATE/REPLACE flags */
1016
    // Set existing with flag CREATE should fail
1017
    if (verbose)
1018
  fprintf(stdout, "Testing CREATE/REPLACE flags use\n");
1019
    if (pxattr::set(tfn, NAMES[0], VALUES[0], pxattr::PXATTR_CREATE)) {
1020
  fprintf(stderr, "Create existing with flag CREATE succeeded !\n");
1021
  exit(1);
1022
    }
1023
    // Set new with flag REPLACE should fail
1024
    if (pxattr::set(tfn, NAMES[1], VALUES[1], pxattr::PXATTR_REPLACE)) {
1025
  fprintf(stderr, "Create new with flag REPLACE succeeded !\n");
1026
  exit(1);
1027
    }
1028
    // Set new with flag CREATE should succeed
1029
    if (!pxattr::set(fd, NAMES[1], VALUES[1], pxattr::PXATTR_CREATE)) {
1030
  fprintf(stderr, "Create new with flag CREATE failed !\n");
1031
  exit(1);
1032
    }
1033
    // Set existing with flag REPLACE should succeed
1034
    if (!pxattr::set(fd, NAMES[0], VALUES[0], pxattr::PXATTR_REPLACE)) {
1035
  fprintf(stderr, "Create existing with flag REPLACE failed !\n");
1036
  exit(1);
1037
    }
1038
    close(fd);
1039
    unlink(tfn);
1040
1041
    if (testbackups())
1042
  exit(0);
1043
    exit(1);
1044
}
942
#endif // Testing pxattr
1045
#endif // Testing pxattr
943
1046
944
#endif // Supported systems.
1047
#endif // Supported systems.