[Forensics-changes] [hashrat] 01/02: Imported Upstream version 1.8.1

Giovani Augusto Ferreira giovani-guest at moszumanska.debian.org
Tue Jul 26 04:21:43 UTC 2016


This is an automated email from the git hooks/post-receive script.

giovani-guest pushed a commit to branch debian
in repository hashrat.

commit 2f4cc0c6e6b72d5dc17a5af63ed323184c059507
Author: Giovani Augusto Ferreira <giovani at riseup.net>
Date:   Tue Jul 26 01:21:00 2016 -0300

    Imported Upstream version 1.8.1
---
 Makefile.in                     |  24 ++--
 check-hash.c                    |   2 +-
 check.sh                        |  10 +-
 command-line-args.c             |  56 ++++++----
 common.c                        |  56 ++++++----
 common.h                        |  13 ++-
 configure                       | 236 ++++++++++++++++++++++++++++++++++++----
 configure.ac                    |  26 +++--
 files.c                         |  40 +++----
 filesigning.c                   |   4 +-
 find.c                          |  76 +++++++------
 fingerprint.c                   |   2 +-
 hashrat.1                       |   6 +-
 libUseful-2.1/ConnectManager.c  |   2 +-
 libUseful-2.1/ConnectionChain.c |   2 +-
 libUseful-2.1/Hash.c            |   2 +-
 libUseful-2.1/Log.c             |  10 +-
 libUseful-2.1/buckets.c         |   2 +-
 libUseful-2.1/file.c            |  46 ++++----
 libUseful-2.1/file.h            |  30 ++---
 libUseful-2.1/openssl.c         |   4 +-
 libUseful-2.1/pty.c             |  41 ++++++-
 libUseful-2.1/socket.c          |  54 +--------
 libUseful-2.1/socket.h          |   7 +-
 libUseful-2.1/sound.c           |   2 +-
 libUseful-2.1/string.c          |  25 ++++-
 libUseful-2.1/tar.c             |   8 +-
 libUseful-2.1/unix_socket.c     |  81 +++++++++++++-
 libUseful-2.1/unix_socket.h     |   3 +-
 main.c                          |  25 ++++-
 xattr.c                         |  45 ++++++--
 31 files changed, 660 insertions(+), 280 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index a53c246..e9a54e6 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -14,40 +14,40 @@ all: hashrat
 
 hashrat: $(OBJ) main.c
 	@cd libUseful-2.1; $(MAKE)
-	gcc $(FLAGS) -o$(EXE) $(OBJ) main.c libUseful-2.1/libUseful-2.1.a $(LIBS) 
+	$(CC) $(FLAGS) -o$(EXE) $(OBJ) main.c libUseful-2.1/libUseful-2.1.a $(LIBS) 
 
 common.o: common.h common.c
-	gcc $(FLAGS) -c common.c
+	$(CC) $(FLAGS) -c common.c
 
 fingerprint.o: fingerprint.h fingerprint.c
-	gcc $(FLAGS) -c fingerprint.c
+	$(CC) $(FLAGS) -c fingerprint.c
 
 files.o: files.h files.c
-	gcc $(FLAGS) -c files.c
+	$(CC) $(FLAGS) -c files.c
 
 filesigning.o: filesigning.h filesigning.c
-	gcc $(FLAGS) -c filesigning.c
+	$(CC) $(FLAGS) -c filesigning.c
 
 find.o: find.h find.c
-	gcc $(FLAGS) -c find.c
+	$(CC) $(FLAGS) -c find.c
 
 check-hash.o: check-hash.h check-hash.c
-	gcc $(FLAGS) -c check-hash.c
+	$(CC) $(FLAGS) -c check-hash.c
 
 xattr.o: xattr.h xattr.c
-	gcc $(FLAGS) -c xattr.c
+	$(CC) $(FLAGS) -c xattr.c
 
 ssh.o: ssh.h ssh.c
-	gcc $(FLAGS) -c ssh.c
+	$(CC) $(FLAGS) -c ssh.c
 
 cgi.o: cgi.h cgi.c
-	gcc $(FLAGS) -c cgi.c
+	$(CC) $(FLAGS) -c cgi.c
 
 memcached.o: memcached.h memcached.c
-	gcc $(FLAGS) -c memcached.c
+	$(CC) $(FLAGS) -c memcached.c
 
 command-line-args.o: command-line-args.h command-line-args.c
-	gcc $(FLAGS) -c command-line-args.c
+	$(CC) $(FLAGS) -c command-line-args.c
 
 check: hashrat
 	@./check.sh
diff --git a/check-hash.c b/check-hash.c
index a82b4d9..620bb19 100644
--- a/check-hash.c
+++ b/check-hash.c
@@ -133,7 +133,7 @@ if (strcmp(ptr,"-")==0)
   ListStream=STREAMFromFD(0);
   STREAMSetTimeout(ListStream,0);
 }
-else ListStream=STREAMOpenFile(ptr, SF_RDONLY);
+else ListStream=STREAMOpenFile(ptr, STREAM_RDONLY);
 
 FP=FingerprintRead(ListStream);
 while (FP)
diff --git a/check.sh b/check.sh
index 6fa4585..dec8510 100755
--- a/check.sh
+++ b/check.sh
@@ -130,6 +130,14 @@ else
 	FailMessage "File hashing BROKEN"
 fi
 
+HR_OUT=`./hashrat -sha1 -trad -r tests | ./hashrat -sha1`
+if [ "$HR_OUT" = "06af1d9f777bbeb1eecd76d71d869089683ded1b" ]
+then
+	OkayMessage "Recursive file hashing works"
+else
+	FailMessage "Recursive file hashing BROKEN"
+fi
+
 HR_INPUT="hash='sha1:5aa622e49b541f9a71409358d2e20feca1fa1f44' mode='100644' uid='0' gid='0' size='621' mtime='1423180289' inode='2359456' path='tests/quotes.txt'"
 HR_OUT=`echo $HR_INPUT | ./hashrat -c 2>&1 | ./hashrat -sha256`
 
@@ -141,7 +149,7 @@ else
 fi
 
 HR_OUT=`./hashrat -r -dups tests`                      
-if [ "$HR_OUT" = "DUPLICATE: tests/quotes.txt of  tests/duplicate.txt" ]
+if [ "$HR_OUT" = "DUPLICATE: tests/quotes.txt of tests/duplicate.txt " ]
 then
 	OkayMessage "Finding duplicate files works"
 else 
diff --git a/command-line-args.c b/command-line-args.c
index 78d4088..a4faa13 100644
--- a/command-line-args.c
+++ b/command-line-args.c
@@ -9,16 +9,16 @@
 
 
 
-//if first item added to Include/Exclude is an include
-//then the program will exclude by default
-void AddIncludeExclude(int Type, const char *Item)
+void AddIncludeExclude(HashratCtx *Ctx, int Type, const char *Item)
 {
 ListNode *Node;
 
+//if we get given an include with no previous excludes, then 
+//set CTX_EXCLUDE as the default
 if (! IncludeExclude)
 {
   IncludeExclude=ListCreate();
-  if (Type==FLAG_INCLUDE) Flags |= FLAG_EXCLUDE;
+  if (Type==CTX_INCLUDE) Ctx->Flags |= CTX_EXCLUDE;
 }
 
 Node=ListAddItem(IncludeExclude, CopyStr(NULL, Item));
@@ -65,7 +65,7 @@ DestroyString(Tempstr);
 
 int CommandLineHandleArg(int argc, char *argv[], int pos, int ParseFlags, int SetFlags, char *VarName, char *VarValue, ListNode *Vars)
 {
-	Flags |= (SetFlags & ~(FLAG_INCLUDE | FLAG_EXCLUDE));
+	Flags |= SetFlags;
 	
 	if (ParseFlags & CMDLINE_ARG_NAMEVALUE)
 	{
@@ -78,9 +78,7 @@ int CommandLineHandleArg(int argc, char *argv[], int pos, int ParseFlags, int Se
 	{
 		strcpy(argv[pos],"");
 		pos++;
-		if (SetFlags & FLAG_INCLUDE) AddIncludeExclude(FLAG_INCLUDE, argv[pos]);
-		else if (SetFlags & FLAG_EXCLUDE) AddIncludeExclude(FLAG_EXCLUDE, argv[pos]);
-		else SetVar(Vars,VarName,argv[pos]);
+		SetVar(Vars,VarName,argv[pos]);
 	}
 	}
 	else if (StrLen(VarName)) SetVar(Vars,VarName,VarValue);
@@ -92,11 +90,25 @@ return(ParseFlags);
 
 
 
-void CommandLineSetCtx(int argc, char *argv[], int i, HashratCtx *Ctx, int Flag, int Encoding)
+void CommandLineSetCtx(int argc, char *argv[], int pos, HashratCtx *Ctx, int Flag, int Encoding)
 {
 if (Encoding > 0) Ctx->Encoding=Encoding;
 Ctx->Flags |= Flag;
-strcpy(argv[i],"");
+strcpy(argv[pos],"");
+
+if (Flag == CTX_INCLUDE) 
+{
+	pos++;
+	AddIncludeExclude(Ctx,CTX_INCLUDE, argv[pos]);
+	strcpy(argv[pos],"");
+}
+else if (Flag == CTX_EXCLUDE) 
+{
+	pos++;
+	AddIncludeExclude(Ctx,CTX_EXCLUDE, argv[pos]);
+	strcpy(argv[pos],"");
+}
+
 }
 
 
@@ -117,7 +129,7 @@ while (ptr)
 	else if (strcasecmp(Token, "txattr")==0) Ctx->Flags |= CTX_STORE_XATTR | CTX_XATTR_ROOT;
 	else if (strcasecmp(Token, "memcached")==0) Ctx->Flags |= CTX_STORE_MEMCACHED;
 	else if (strcasecmp(Token, "mcd")==0) Ctx->Flags |= CTX_STORE_MEMCACHED;
-	else if (! Ctx->Aux) Ctx->Aux=STREAMOpenFile(Token,SF_WRONLY | SF_CREAT | SF_TRUNC);
+	else if (! Ctx->Aux) Ctx->Aux=STREAMOpenFile(Token,STREAM_WRONLY | STREAM_CREAT | STREAM_TRUNC);
 
 ptr=GetToken(ptr,",",&Token,0);
 }
@@ -126,6 +138,7 @@ strcpy(argv[i],"");
 DestroyString(Token);
 }
 
+
 //this is the main parsing function that goes through the command-line args
 HashratCtx *CommandLineParseArgs(int argc,char *argv[])
 {
@@ -209,13 +222,13 @@ else if (
 else if (strcmp(argv[i],"-C")==0)
 {
 	Ctx->Action = ACT_CHECK;
-	ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_RECURSE, "", "",Ctx->Vars);
-	strcpy(argv[i],"");
+	CommandLineSetCtx(argc, argv, i, Ctx, CTX_RECURSE,0);
 }
 else if (strcmp(argv[i],"-Cf")==0)
 {
 	Ctx->Action = ACT_CHECK;
-	ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_RECURSE | FLAG_OUTPUT_FAILS, "", "",Ctx->Vars);
+	CommandLineSetCtx(argc, argv, i, Ctx, CTX_RECURSE,0);
+	ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_OUTPUT_FAILS, "", "",Ctx->Vars);
 	strcpy(argv[i],"");
 }
 else if (strcmp(argv[i],"-c")==0)
@@ -327,21 +340,21 @@ else if (strcmp(argv[i],"-z85")==0) CommandLineSetCtx(argc, argv, i, Ctx,  0, EN
 else if (strcmp(argv[i],"-d")==0) CommandLineSetCtx(argc, argv, i, Ctx, CTX_DEREFERENCE,0);
 else if (strcmp(argv[i],"-X")==0) CommandLineSetCtx(argc, argv, i, Ctx, CTX_EXES,0);
 else if (strcmp(argv[i],"-exe")==0) CommandLineSetCtx(argc, argv, i, Ctx, CTX_EXES,0);
+else if (strcmp(argv[i],"-r")==0) CommandLineSetCtx(argc, argv, i, Ctx, CTX_RECURSE,0);
+else if (strcmp(argv[i],"-fs")==0) CommandLineSetCtx(argc, argv, i, Ctx, CTX_ONE_FS,0);
 else if (strcmp(argv[i],"-n")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, CMDLINE_ARG_NAMEVALUE, 0, "Output:Length", "",Ctx->Vars);
 else if (strcmp(argv[i],"-hmac")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, CMDLINE_ARG_NAMEVALUE, FLAG_HMAC, "EncryptionKey", "",Ctx->Vars);
 else if (strcmp(argv[i],"-idfile")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, CMDLINE_ARG_NAMEVALUE, 0,  "SshIdFile", "",Ctx->Vars);
-else if (strcmp(argv[i],"-r")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_RECURSE, "", "",Ctx->Vars);
 else if (strcmp(argv[i],"-f")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, CMDLINE_FROM_LISTFILE, 0, "", "",Ctx->Vars);
-else if (strcmp(argv[i],"-i")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, CMDLINE_ARG_NAMEVALUE, FLAG_INCLUDE , "", "",Ctx->Vars);
-else if (strcmp(argv[i],"-x")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, CMDLINE_ARG_NAMEVALUE, FLAG_EXCLUDE , "", "",Ctx->Vars);
-else if (strcmp(argv[i],"-dirmode")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_DIRMODE | FLAG_RECURSE, "", "",Ctx->Vars);
+else if (strcmp(argv[i],"-i")==0) CommandLineSetCtx(argc, argv, i, Ctx, CTX_INCLUDE,0);
+else if (strcmp(argv[i],"-x")==0) CommandLineSetCtx(argc, argv, i, Ctx, CTX_EXCLUDE,0);
+else if (strcmp(argv[i],"-dirmode")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_DIRMODE, "", "",Ctx->Vars);
 else if (strcmp(argv[i],"-devmode")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_DIRMODE | FLAG_DEVMODE, "", "",Ctx->Vars);
 else if (strcmp(argv[i],"-lines")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_LINEMODE, "", "",Ctx->Vars);
 else if (strcmp(argv[i],"-rawlines")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_RAW|FLAG_LINEMODE, "", "",Ctx->Vars);
 else if (strcmp(argv[i],"-hide-input")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_HIDE_INPUT, "", "",Ctx->Vars);
 else if (strcmp(argv[i],"-star-input")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_STAR_INPUT, "", "",Ctx->Vars);
 else if (strcmp(argv[i],"-rl")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_RAW|FLAG_LINEMODE, "", "",Ctx->Vars);
-else if (strcmp(argv[i],"-fs")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_ONE_FS, "", "",Ctx->Vars);
 else if (strcmp(argv[i],"-xattr")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, CMDLINE_XATTR, 0, "", "",Ctx->Vars);
 else if (strcmp(argv[i],"-txattr")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, CMDLINE_TXATTR, 0, "", "",Ctx->Vars);
 else if (strcmp(argv[i],"-cache")==0) CommandLineSetCtx(argc, argv, i, Ctx,   CTX_XATTR_CACHE,0);
@@ -351,6 +364,7 @@ else if (strcmp(argv[i],"-S")==0) ParseFlags |= CommandLineHandleArg(argc, argv,
 else if (strcmp(argv[i],"-net")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_NET, "", "",Ctx->Vars);
 else if (strcmp(argv[i],"-memcached")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, CMDLINE_ARG_NAMEVALUE|CMDLINE_MEMCACHED, 0, "Memcached:Server", "",Ctx->Vars);
 else if (strcmp(argv[i],"-mcd")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, CMDLINE_ARG_NAMEVALUE| CMDLINE_MEMCACHED, 0, "Memcached:Server", "",Ctx->Vars);
+else if (strcmp(argv[i],"-xsel")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_XSELECT, "", "",Ctx->Vars);
 else if (strcmp(argv[i],"-v")==0) ParseFlags |= CommandLineHandleArg(argc, argv, i, 0, FLAG_VERBOSE, "", "",Ctx->Vars);
 else if (
 					(strcmp(argv[i],"-t")==0) ||
@@ -530,13 +544,13 @@ printf("  %-15s %s\n","-net", "Treat 'file' arguments as either ssh or http URLs
 printf("  %-15s %s\n","", "URLs are in the format ssh://[username]:[password]@[host]:[port] or http://[username]:[password]@[host]:[port]..");
 printf("  %-15s %s\n","-idfile <path>", "Path to an ssh private key file to use to authenticate INSTEAD OF A PASSWORD when pulling files via ssh.");
 printf("  %-15s %s\n","-xattr", "Use eXtended file ATTRibutes. In hash mode, store hashes in the file attributes, in check mode compare against hashes stored in file attributes.");
-printf("  %-15s %s\n","-txattr", "Use TRUSTED eXtended file ATTRibutes. In hash mode, store hashes in 'trusted' file attributes. 'trusted' attributes can only be read and written by root.");
+printf("  %-15s %s\n","-txattr", "Use TRUSTED eXtended file ATTRibutes. In hash mode, store hashes in 'trusted' file attributes. 'trusted' attributes can only be read and written by root. Under freebsd this menas SYSTEM attributes.");
 printf("  %-15s %s\n","-attrs", "comma-separated list of filesystem attribute names to be set to the value of the hash.");
 printf("  %-15s %s\n","-cache", "Use hashes stored in 'user' xattr if they're younger than the mtime of the file. This speeds up outputting hashes.");
 printf("  %-15s %s\n","-u <types>", "Update. In checking mode, update hashes for the files as you go. <types> is a comma-separated list of things to update, which can be 'xattr' 'memcached' or a file name. This will update these targets with the hash that was found at the time of checking.");
 printf("  %-15s %s\n","-hide-input", "When reading data from stdin in linemode, set the terminal to not echo characters, thus hiding typed input.");
 printf("  %-15s %s\n","-star-input", "When reading data from stdin in linemode replace characters with stars.");
-
+printf("  %-15s %s\n","-xsel", "Update X11 clipboard and primary selections to the current hash. This works using Xterm command sequences. The xterm resource 'allowWindowOps' must be set to 'true' for this to work.");
 
 printf("\n\nHashrat can also detect if it's being run under any of the following names (e.g., via symlinks)\n\n");
 printf("  %-15s %s\n","md5sum","run with '-trad -md5'");
diff --git a/common.c b/common.c
index c3b9520..b9cf8db 100644
--- a/common.c
+++ b/common.c
@@ -31,15 +31,15 @@ free(Ctx);
 
 int HashratOutputInfo(HashratCtx *Ctx, STREAM *Out, char *Path, struct stat *Stat, char *Hash)
 {
-char *Tempstr=NULL, *ptr; 
+char *Line=NULL, *Tempstr=NULL, *ptr; 
 char *p_Type="unknown";
 
-if (Flags & FLAG_TRAD_OUTPUT) Tempstr=MCopyStr(Tempstr,Hash, "  ", Path,NULL);
+if (Flags & FLAG_TRAD_OUTPUT) Line=MCopyStr(Line,Hash, "  ", Path,"\n",NULL);
 else if (Flags & FLAG_BSD_OUTPUT) 
 {
-	Tempstr=CopyStr(Tempstr,Ctx->HashType);
-	for (ptr=Tempstr; *ptr != '\0'; ptr++) *ptr=toupper(*ptr);
-	Tempstr=MCatStr(Tempstr, " (", Path, ") = ", Hash, NULL);
+	Line=CopyStr(Line,Ctx->HashType);
+	for (ptr=Line; *ptr != '\0'; ptr++) *ptr=toupper(*ptr);
+	Line=MCatStr(Line, " (", Path, ") = ", Hash, "\n",NULL);
 }
 else
 {
@@ -60,26 +60,40 @@ else
     time_t    st_ctime;   // time of last status change 
 	*/
 
-if (S_ISREG(Stat->st_mode)) p_Type="file";
-else if (S_ISDIR(Stat->st_mode)) p_Type="dir";
-else if (S_ISLNK(Stat->st_mode)) p_Type="link";
-else if (S_ISSOCK(Stat->st_mode)) p_Type="socket";
-else if (S_ISFIFO(Stat->st_mode)) p_Type="fifo";
-else if (S_ISCHR(Stat->st_mode)) p_Type="chrdev";
-else if (S_ISBLK(Stat->st_mode)) p_Type="blkdev";
-
-#if _FILE_OFFSET_BITS == 64
-	Tempstr=FormatStr(Tempstr,"hash='%s:%s' type='%s' mode='%o' uid='%lu' gid='%lu' size='%llu' mtime='%lu' inode='%llu' path='%s'",Ctx->HashType,Hash,p_Type,Stat->st_mode,Stat->st_uid,Stat->st_gid,Stat->st_size,Stat->st_mtime,Stat->st_ino,Path);
-#else
-	Tempstr=FormatStr(Tempstr,"hash='%s:%s' type='%s' mode='%o' uid='%lu' gid='%lu' size='%lu' mtime='%lu' inode='%lu' path='%s'",Ctx->HashType,Hash,p_Type,Stat->st_mode,Stat->st_uid,Stat->st_gid,Stat->st_size,Stat->st_mtime,Stat->st_ino,Path);
-#endif
-}
+	if (S_ISREG(Stat->st_mode)) p_Type="file";
+	else if (S_ISDIR(Stat->st_mode)) p_Type="dir";
+	else if (S_ISLNK(Stat->st_mode)) p_Type="link";
+	else if (S_ISSOCK(Stat->st_mode)) p_Type="socket";
+	else if (S_ISFIFO(Stat->st_mode)) p_Type="fifo";
+	else if (S_ISCHR(Stat->st_mode)) p_Type="chrdev";
+	else if (S_ISBLK(Stat->st_mode)) p_Type="blkdev";
+	
+	Line=FormatStr(Line,"hash='%s:%s' type='%s' mode='%o' uid='%lu' gid='%lu' ", Ctx->HashType,Hash,p_Type,Stat->st_mode,Stat->st_uid,Stat->st_gid);
+	
+	//This dance is to handle the fact that on some 32-bit OS, like openbsd, stat with have 64-bit members
+	//even if we've not asked for 'largefile' support, while on Linux it will have 32-bit members
+
+	//Let's hope the compiler optimizes the fuck out of this
 
-Tempstr=CatStr(Tempstr,"\n");
+	if (sizeof(Stat->st_size)==sizeof(unsigned long long)) Tempstr=FormatStr(Tempstr, "size='%llu' ",Stat->st_size);
+	else Tempstr=FormatStr(Tempstr, "size='%lu' ",Stat->st_size);
+	Line=CatStr(Line, Tempstr);
+
+	if (sizeof(Stat->st_mtime)==sizeof(unsigned long long)) Tempstr=FormatStr(Tempstr, "mtime='%llu' ",Stat->st_mtime);
+	else Tempstr=FormatStr(Tempstr, "mtime='%lu' ",Stat->st_mtime);
+	Line=CatStr(Line, Tempstr);
+	
+	if (sizeof(Stat->st_ino)==sizeof(unsigned long long)) Tempstr=FormatStr(Tempstr, "inode='%llu' ",Stat->st_ino);
+	else Tempstr=FormatStr(Tempstr, "inode='%lu' ",Stat->st_ino);
+	Line=CatStr(Line, Tempstr);
+	
+	Line=MCatStr(Line,"path='",Path,"'\n",NULL);
+}
 
-STREAMWriteString(Tempstr,Out);
+STREAMWriteString(Line,Out);
 
 DestroyString(Tempstr);
+DestroyString(Line);
 
 return(TRUE);
 }
diff --git a/common.h b/common.h
index de5116d..fe8188b 100644
--- a/common.h
+++ b/common.h
@@ -25,20 +25,17 @@
 #define ACT_CHECKBACKUP 25
 
 
-#define FLAG_RECURSE 1
 //Two flags with the same values, but used in different contexts
 #define FLAG_ERROR 2
 #define FLAG_VERBOSE 2
 #define FLAG_DIRMODE 4
 #define FLAG_DEVMODE 8
-#define FLAG_ONE_FS  16
 #define FLAG_DIR_INFO 32
 #define FLAG_TRAD_OUTPUT 64
 #define FLAG_BSD_OUTPUT  128 
+#define FLAG_XSELECT     256 
 #define FLAG_MEMCACHED  1024
 #define FLAG_OUTPUT_FAILS 2048 
-#define FLAG_INCLUDE      8192
-#define FLAG_EXCLUDE     16384
 #define FLAG_FULLCHECK   32768
 #define FLAG_HMAC        65536
 #define FLAG_HIDE_INPUT 131072
@@ -49,7 +46,9 @@
 #define FLAG_NET       8388608
 #define FLAG_UPDATE   16777216
 
-#define CTX_CACHED		1
+#define CTX_CACHED   1
+#define CTX_RECURSE  2
+#define CTX_ONE_FS  16
 #define CTX_DEREFERENCE 128
 #define CTX_STORE_XATTR 256
 #define CTX_STORE_MEMCACHED 512
@@ -57,6 +56,8 @@
 #define CTX_XATTR_ROOT 2048
 #define CTX_XATTR_CACHE 4096
 #define CTX_EXES 8192
+#define CTX_INCLUDE 16384
+#define CTX_EXCLUDE 32768
 
 #define INEX_INCLUDE 1
 #define INEX_EXCLUDE 2
@@ -74,7 +75,7 @@
 
 #define BLOCKSIZE 4096
 
-#define VERSION "1.8"
+#define VERSION "1.8.1"
 
 
 typedef struct
diff --git a/configure b/configure
index cf6a3f1..ffb92ed 100755
--- a/configure
+++ b/configure
@@ -584,6 +584,42 @@ PACKAGE_URL=
 
 ac_unique_file="main.c"
 enable_option_checking=no
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
 ac_subst_vars='LTLIBOBJS
 LIBOBJS
 EGREP
@@ -1471,6 +1507,124 @@ fi
   as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_run
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
@@ -3363,17 +3517,75 @@ fi
 
 # Check whether --enable-xattr was given.
 if test "${enable_xattr+set}" = set; then :
-  enableval=$enable_xattr; cf_use_xattr=$enableval
+  enableval=$enable_xattr; cf_enable_xattr=$enableval
 fi
 
 
 
-if test "$cf_use_xattr" = "yes"
+if test "$cf_enable_xattr" = "yes"
+then
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/extattr.h" "ac_cv_header_sys_extattr_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_extattr_h" = xyes; then :
+  cf_extended_attribs=extattr
+fi
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/xattr.h" "ac_cv_header_sys_xattr_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_xattr_h" = xyes; then :
+  cf_extended_attribs=xattr
+fi
+
+
+fi
+
+
+if test "$cf_extended_attribs" = "extattr"
+then
+$as_echo "#define USE_EXTATTR 1" >>confdefs.h
+
+elif test "$cf_extended_attribs" = "xattr"
 then
 $as_echo "#define USE_XATTR 1" >>confdefs.h
 
 fi
 
+echo
+echo
+echo "############# Hashrat Build Config: #############"
+if test "$ac_cv_sys_file_offset_bits" = "64"
+then
+echo "Largefiles ( > 2GB ) enabled"
+else
+echo "Largefiles ( > 2GB ) NOT enabled"
+fi
+
+if test "$cf_extended_attribs" = "xattr"
+then
+echo "File system attributes (xattr) enabled"
+elif test "$cf_extended_attribs" = "extattr"
+then
+echo "File system attributes (extattr) enabled"
+else
+echo "File system attributes NOT enabled"
+fi
+
 
 ac_config_files="$ac_config_files Makefile"
 
@@ -4684,23 +4896,3 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
 fi
 
 
-
-echo
-echo
-echo "############# Hashrat Build Config: #############"
-if test "$ac_cv_sys_file_offset_bits" = "64"
-then
-echo "Largefiles ( > 2GB ) enabled"
-else
-echo "Largefiles ( > 2GB ) NOT enabled"
-fi
-
-if test "$cf_use_xattr" = "yes"
-then
-echo "File system attributes (xattr) enabled"
-else
-echo "File system attributes (xattr) NOT enabled"
-fi
-
-
-
diff --git a/configure.ac b/configure.ac
index e14ccfe..472002d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -12,18 +12,23 @@ AC_PROG_INSTALL
 AC_HEADER_STDC 
 AC_SYS_LARGEFILE
 
-AC_ARG_ENABLE(xattr, [  --enable-xattr       enable extended file attributes support], cf_use_xattr=$enableval )
+AC_ARG_ENABLE(xattr, [  --enable-xattr       enable extended file attributes support], cf_enable_xattr=$enableval )
 
 
-if test "$cf_use_xattr" = "yes"
+if test "$cf_enable_xattr" = "yes"
 then
-AC_DEFINE([USE_XATTR])
+AC_CHECK_HEADER([sys/extattr.h],[cf_extended_attribs=extattr],[])
+AC_CHECK_HEADER([sys/xattr.h],[cf_extended_attribs=xattr],[])
 fi
 
 
-dnl read Makefile.in and write Makefile 
-AC_OUTPUT(Makefile)
-
+if test "$cf_extended_attribs" = "extattr"
+then
+AC_DEFINE([USE_EXTATTR], [1])
+elif test "$cf_extended_attribs" = "xattr"
+then
+AC_DEFINE([USE_XATTR], [1])
+fi
 
 echo
 echo
@@ -35,12 +40,17 @@ else
 echo "Largefiles ( > 2GB ) NOT enabled"
 fi
 
-if test "$cf_use_xattr" = "yes"
+if test "$cf_extended_attribs" = "xattr"
 then
 echo "File system attributes (xattr) enabled"
+elif test "$cf_extended_attribs" = "extattr"
+then
+echo "File system attributes (extattr) enabled"
 else
-echo "File system attributes (xattr) NOT enabled"
+echo "File system attributes NOT enabled"
 fi
 
 
+dnl read Makefile.in and write Makefile 
+AC_OUTPUT(Makefile)
 
diff --git a/files.c b/files.c
index d2adfe6..f313930 100644
--- a/files.c
+++ b/files.c
@@ -45,13 +45,13 @@ int FileType(char *Path, int FTFlags, struct stat *Stat)
 }
 
 
-int IsIncluded(char *Path, struct stat *FStat)
+int IsIncluded(HashratCtx *Ctx, char *Path, struct stat *FStat)
 {
 ListNode *Curr;
 char *mptr, *dptr;
 int result=TRUE;
 
-if (Flags & FLAG_EXCLUDE) result=FALSE;
+if (Ctx->Flags & CTX_EXCLUDE) result=FALSE;
 if (S_ISDIR(FStat->st_mode)) result=TRUE;
 
 Curr=ListGetNext(IncludeExclude);
@@ -187,8 +187,8 @@ switch (Type)
 		if ((! StrLen(Path)) || (strcmp(Path,"-")==0)) S=STREAMFromFD(0);
 		else
 		{
-			if (Ctx->Flags & CTX_DEREFERENCE) S=STREAMOpenFile(Path,SF_RDONLY|SF_SYMLINK_OK);
-			else S=STREAMOpenFile(Path,SF_RDONLY);
+			if (Ctx->Flags & CTX_DEREFERENCE) S=STREAMOpenFile(Path,STREAM_RDONLY|STREAM_SYMLINK_OK);
+			else S=STREAMOpenFile(Path,STREAM_RDONLY);
 		}
 	break;
 }
@@ -315,23 +315,23 @@ int ConsiderItem(HashratCtx *Ctx, char *Path, struct stat *FStat)
 	switch (Type)
 	{
 		case FT_SSH:
-			if (SSHGlob(Ctx, Path, NULL) > 1) return(FLAG_RECURSE);
+			if (SSHGlob(Ctx, Path, NULL) > 1) return(CTX_RECURSE);
 		break;
 
 		case FT_DIR:
-		if (Flags & FLAG_RECURSE) return(FLAG_RECURSE);
+		if (Ctx->Flags & CTX_RECURSE) return(CTX_RECURSE);
 		break;
 	}
 
 	if (FStat)
 	{
-	if (Flags & FLAG_ONE_FS)
+	if (Ctx->Flags & CTX_ONE_FS)
 	{
 		if (StartingFS==0) StartingFS=FStat->st_dev;
-		else if (FStat->st_dev != StartingFS) return(FLAG_ONE_FS);
+		else if (FStat->st_dev != StartingFS) return(CTX_ONE_FS);
 	}
-	if ((Ctx->Flags & CTX_EXES) && (! (FStat->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))) return(FLAG_EXCLUDE);
-	if (! IsIncluded(Path, FStat)) return(FLAG_EXCLUDE);
+	if ((Ctx->Flags & CTX_EXES) && (! (FStat->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))) return(CTX_EXCLUDE);
+	if (! IsIncluded(Ctx,Path, FStat)) return(CTX_EXCLUDE);
 	}
 
 	return(0);
@@ -359,7 +359,7 @@ char *Tempstr=NULL;
 		break;
 
 		case FT_DIR:
-		if (Flags & FLAG_RECURSE) return(FLAG_RECURSE);
+		if (Ctx->Flags & CTX_RECURSE) return(CTX_RECURSE);
 		else ProcessData(HashStr, Ctx, (char *) &FStat->st_ino, sizeof(ino_t));
 		break;
 
@@ -440,9 +440,9 @@ case ACT_CHECK:
 			{
 				if (HashratCheckFile(Ctx, Path, Stat, HashStr, FP)) MatchCount++;
 			}
-	   	else HandleCheckFail(Path, "Changed or new");
+			else HandleCheckFail(Path, "Changed or new");
 			TFingerprintDestroy(FP);	
-			}
+		}
 		else if (Flags & FLAG_VERBOSE) fprintf(stderr,"ZERO LENGTH FILE: %s\n",Path);
 	}
 break;
@@ -468,9 +468,9 @@ case ACT_CHECK_MEMCACHED:
 		{
 		HashItem(Ctx, Ctx->HashType, Path, Stat, &HashStr);
 		FP=(TFingerprint *) calloc(1,sizeof(TFingerprint));
-    if (Flags & FLAG_NET) FP->Path=MCopyStr(FP->Path, Path);
-    else FP->Path=MCopyStr(FP->Path,"hashrat://",LocalHost,Path,NULL);
-    FP->Hash=MemcachedGet(FP->Hash, FP->Path);
+		if (Flags & FLAG_NET) FP->Path=MCopyStr(FP->Path, Path);
+		else FP->Path=MCopyStr(FP->Path,"hashrat://",LocalHost,Path,NULL);
+		FP->Hash=MemcachedGet(FP->Hash, FP->Path);
 
 		if (FP) HashratCheckFile(Ctx, Path, NULL, HashStr, FP);
 		else fprintf(stderr,"ERROR: No stored hash for '%s'\n",Path);
@@ -516,7 +516,7 @@ case ACT_FINDDUPLICATES:
 			}
 			else 
 			{
-				FP=TFingerprintCreate(HashStr, Ctx->HashType, Path, "");
+				FP=TFingerprintCreate(HashStr, Ctx->HashType, "", Path);
 				DiffCount++;
 				MatchAdd(FP, Path, 0);
 			}
@@ -590,11 +590,11 @@ char *HashStr=NULL;
 
 				switch (ConsiderItem(Ctx, Path, Stat))
 				{
-					case FLAG_EXCLUDE:
-					case FLAG_ONE_FS:
+					case CTX_EXCLUDE:
+					case CTX_ONE_FS:
 					break;
 
-					case FLAG_RECURSE:
+					case CTX_RECURSE:
 					HashratRecurse(Ctx, Path, &HashStr, 0);
 					break;
 
diff --git a/filesigning.c b/filesigning.c
index 11ee1e4..85ca83e 100644
--- a/filesigning.c
+++ b/filesigning.c
@@ -8,7 +8,7 @@ char *Tempstr=NULL, *HashStr=NULL;
 double pos;
 THash *Hash;
 
-S=STREAMOpenFile(Path, SF_RDWR);
+S=STREAMOpenFile(Path, STREAM_RDWR);
 if (! S) return;
 
 
@@ -90,7 +90,7 @@ char *Tempstr=NULL, *HashStr=NULL;
 THash *Hash, *tmpHash;
 int LineCount=0;
 
-S=STREAMOpenFile(Path, SF_RDWR);
+S=STREAMOpenFile(Path, STREAM_RDWR);
 if (! S) return(FALSE);
 
 Hash=HashInit(Ctx->HashType);
diff --git a/find.c b/find.c
index 5bbcb9a..2fe1fc5 100644
--- a/find.c
+++ b/find.c
@@ -39,6 +39,7 @@ TFingerprint *M1, *M2;
 M1=(TFingerprint *) i1;
 M2=(TFingerprint *) i2;
 
+
 return(strcmp(M1->Hash, M2->Hash));
 }
 
@@ -59,8 +60,8 @@ void *vptr;
 	}
 	else
 	{
-			vptr=tsearch(FP, &Tree, MatchCompareFunc);
-			Item=*(TFingerprint **) vptr;
+		vptr=tsearch(FP, &Tree, MatchCompareFunc);
+		Item=*(TFingerprint **) vptr;
 		if (strcmp(Item->Path, FP->Path) !=0)
 		{
 			while (Item->Next !=NULL) Item=(TFingerprint *) Item->Next;
@@ -73,7 +74,7 @@ void *vptr;
 }
 
 
-TFingerprint *FindInMatches(HashratCtx *Ctx, TFingerprint *Head, const char *Path)
+TFingerprint *FindPathMatches(HashratCtx *Ctx, TFingerprint *Head, const char *Path)
 {
 TFingerprint *Item=NULL, *Prev=NULL;
 
@@ -108,39 +109,52 @@ void *ptr;
 if (! StrLen(Path)) return(NULL);
 
 Lookup=TFingerprintCreate(HashStr,"","",Path);
-if (Ctx->Action==ACT_FINDMATCHES_MEMCACHED)
-{
-		Lookup->Data=MemcachedGet(Lookup->Data, Lookup->Hash);
-		if (StrLen(Lookup->Data)) Result=TFingerprintCreate(Lookup->Hash, Lookup->HashType, Lookup->Data, "");
-}
-else
+switch (Ctx->Action)
 {
-		ptr=tfind(Lookup, &Tree, MatchCompareFunc);
-		if (ptr) 
-		{
-			Item=FindInMatches(Ctx, *(TFingerprint **) ptr, Path);
+	case ACT_FINDMATCHES_MEMCACHED:
+	Lookup->Data=MemcachedGet(Lookup->Data, Lookup->Hash);
+	if (StrLen(Lookup->Data)) Result=TFingerprintCreate(Lookup->Hash, Lookup->HashType, Lookup->Data, "");
+	break;
+
+	case ACT_FINDDUPLICATES:
+	case ACT_FINDMATCHES:
+	ptr=tfind(Lookup, &Tree, MatchCompareFunc);
+	if (ptr)
+	{
+	Item=*(TFingerprint **) ptr;
+
+	//we have to make a copy because 'Result' is destroyed by parent function
+	Result=TFingerprintCreate(Item->Hash, Item->HashType, Item->Data, Item->Path);
+	}
+	break;
 
-      if (Item) 
+	default:
+	ptr=tfind(Lookup, &Tree, MatchCompareFunc);
+	if (ptr) 
+	{
+		Item=FindPathMatches(Ctx, *(TFingerprint **) ptr, Path);
+		if (Item) 
+		{
+		Result=TFingerprintCreate(Item->Hash, Item->HashType, Item->Data, Item->Path);
+		if (Ctx->Action==ACT_CHECK)
+		{
+			if (Item==Head) 
 			{
-			Result=TFingerprintCreate(Item->Hash, Item->HashType, Item->Data, Item->Path);
-      if (Ctx->Action==ACT_CHECK)
-      {
-        if (Item==Head) 
+				if (Item->Next==NULL) 
 				{
-					if (Item->Next==NULL) 
-					{
-						// tree functions take a copy of the 'head' item, so we cannot
-						// destroy it. No idea how they do this, it's magic
-						// however we can destroy non-head items that we hang off
-						// the tree
-						tdelete(Lookup, &Tree, MatchCompareFunc);
-					}
-					else Item->Path=CopyStr(Item->Path, "");
+					// tree functions take a copy of the 'head' item, so we cannot
+					// destroy it. No idea how they do this, it's magic
+					// however we can destroy non-head items that we hang off
+					// the tree
+					tdelete(Lookup, &Tree, MatchCompareFunc);
 				}
-				//else TFingerprintDestroy(Item);
-      }
-      }
-    }
+				else Item->Path=CopyStr(Item->Path, "");
+			}
+			//else TFingerprintDestroy(Item);
+		}
+		}
+	}
+	break;
 }
 
 TFingerprintDestroy(Lookup);
diff --git a/fingerprint.c b/fingerprint.c
index 31eb185..e99ec23 100644
--- a/fingerprint.c
+++ b/fingerprint.c
@@ -57,7 +57,7 @@ TFingerprint *Item;
 
   Item=(TFingerprint *) calloc(1,sizeof(TFingerprint));
   Item->Hash=CopyStr(Item->Hash, Hash);
- 	strlwr(Item->Hash);
+  strlwr(Item->Hash);
   Item->HashType=CopyStr(Item->HashType, HashType);
   Item->Data=CopyStr(Item->Data, Data);
   Item->Path=CopyStr(Item->Path, Path);
diff --git a/hashrat.1 b/hashrat.1
index 0abaa1e..0883e4c 100644
--- a/hashrat.1
+++ b/hashrat.1
@@ -241,7 +241,7 @@ Use eXtended \fIfile\fP ATTRibutes. In \fIhash\fP mode, store \fIhashes\fP in th
 .TP
 .B
 \fB-txattr\fP
-Use TRUSTED eXtended \fIfile\fP ATTRibutes. In \fIhash\fP mode, store \fIhashes\fP in trusted \fIfile\fP attributes. The trusted attributes can only be read and written by root.
+Use TRUSTED eXtended \fIfile\fP ATTRibutes. In \fIhash\fP mode, store \fIhashes\fP in trusted \fIfile\fP attributes. The trusted attributes can only be read and written by root. Under FreeBSD this means 'SYSTEM' attributes.
 .TP
 .B
 \fB-cache\fP
@@ -257,6 +257,10 @@ or a \fIfile\fP name. This will update these targets with the \fIhash\fP that wa
 When reading data from stdin in linemode, set the terminal \fIto\fP not echo characters, thus hiding typed \fIinput\fP.
 .TP
 .B
+\fB-xsel\fP
+Update X11 clipboard and primary selections to the current hash. This works using Xterm command sequences. The xterm resource 'allowWindowOps' must be set to 'true' for this to work.
+.TP
+.B
 \fB-star\fP-\fIinput\fP
 When reading data from stdin in linemode replace characters with stars.
 .SH NOTES
diff --git a/libUseful-2.1/ConnectManager.c b/libUseful-2.1/ConnectManager.c
index 32a6420..7f90045 100644
--- a/libUseful-2.1/ConnectManager.c
+++ b/libUseful-2.1/ConnectManager.c
@@ -267,7 +267,7 @@ while (1)
 				{
 					if (STREAMIsConnected(S)) 
 					{
-						STREAMSetFlags(S, 0, SF_NONBLOCK);
+						STREAMSetFlags(S, 0, STREAM_NONBLOCK);
 						if (Item->OnConnect) Item->OnConnect(Item);
 					}
 
diff --git a/libUseful-2.1/ConnectionChain.c b/libUseful-2.1/ConnectionChain.c
index fd6810f..e4b0702 100644
--- a/libUseful-2.1/ConnectionChain.c
+++ b/libUseful-2.1/ConnectionChain.c
@@ -45,7 +45,7 @@ STREAM *LocalFile;
 
 Tempstr=FormatStr(Tempstr,"rm -f %s ; touch %s; chmod 0600 %s\n",KeyFile,KeyFile,KeyFile);
 STREAMWriteLine(Tempstr,S);
-LocalFile=STREAMOpenFile(LocalPath,SF_RDONLY);
+LocalFile=STREAMOpenFile(LocalPath,STREAM_RDONLY);
 if (LocalFile)
 {
 Line=STREAMReadLine(Line,LocalFile);
diff --git a/libUseful-2.1/Hash.c b/libUseful-2.1/Hash.c
index 9f62945..ae9234b 100644
--- a/libUseful-2.1/Hash.c
+++ b/libUseful-2.1/Hash.c
@@ -615,7 +615,7 @@ STREAM *S;
 char *Tempstr=NULL;
 int result;
 
-S=STREAMOpenFile(Path,SF_RDONLY);
+S=STREAMOpenFile(Path,STREAM_RDONLY);
 if (! S) return(FALSE);
 
 Hash=HashInit(Type);
diff --git a/libUseful-2.1/Log.c b/libUseful-2.1/Log.c
index 3264065..546e73c 100644
--- a/libUseful-2.1/Log.c
+++ b/libUseful-2.1/Log.c
@@ -43,7 +43,7 @@ TLogFile *LogFileGetEntry(const char *FileName)
 		else if (strcmp(FileName,"SYSLOG")==0) S=STREAMCreate();
 		else
 		{
-			S=STREAMOpenFile(FileName,SF_CREAT | SF_APPEND | SF_WRONLY);
+			S=STREAMOpenFile(FileName,STREAM_CREAT | STREAM_APPEND | STREAM_WRONLY);
 		}
 
 		if (S)
@@ -129,7 +129,7 @@ STREAM *LogFileInternalDoRotate(TLogFile *LogFile)
 			
     STREAMClose(LogFile->S);
 		if (PrevPath) rename(LogFile->Path,PrevPath);
-    LogFile->S=STREAMOpenFile(LogFile->Path,SF_CREAT | SF_APPEND | SF_WRONLY);
+    LogFile->S=STREAMOpenFile(LogFile->Path,STREAM_CREAT | STREAM_APPEND | STREAM_WRONLY);
   }
   }
 
@@ -216,8 +216,8 @@ int LogFileInternalWrite(TLogFile *LF, STREAM *S, int Flags, const char *Str)
 
 		if (S)
 		{
-			if (Flags & LOGFILE_LOCK) S->Flags |= SF_WRLOCK;
-			else S->Flags &= ~SF_WRLOCK;
+			if (Flags & LOGFILE_LOCK) S->Flags |= STREAM_WRLOCK;
+			else S->Flags &= ~STREAM_WRLOCK;
 
 			if (LF && ((Now.tv_sec-LF->LastFlushTime) > LF->FlushInterval)) Flags |= LOGFILE_FLUSH;
 			STREAMWriteLine(LogStr,S);
@@ -320,7 +320,7 @@ int result=FALSE;
 
     LogFile=LogFileGetEntry(LogPath);
     LogFileClose(TmpLogPath);
-    S=STREAMOpenFile(TmpLogPath,SF_RDONLY);
+    S=STREAMOpenFile(TmpLogPath,STREAM_RDONLY);
     if (LogFile && S)
     {
 
diff --git a/libUseful-2.1/buckets.c b/libUseful-2.1/buckets.c
index 8635f2f..20a36ad 100644
--- a/libUseful-2.1/buckets.c
+++ b/libUseful-2.1/buckets.c
@@ -67,7 +67,7 @@ STREAM *S;
 char *Tempstr=NULL;
 clock_t start, mid, end;
 
-S=STREAMOpenFile(argv[1],SF_RDONLY);
+S=STREAMOpenFile(argv[1],STREAM_RDONLY);
 start=clock();
 Tempstr=STREAMReadLine(Tempstr,S);
 while (Tempstr)
diff --git a/libUseful-2.1/file.c b/libUseful-2.1/file.c
index dd73979..fb601e5 100644
--- a/libUseful-2.1/file.c
+++ b/libUseful-2.1/file.c
@@ -89,7 +89,7 @@ int val;
 
         //Handling nonblock flag involves setting nonblock on or off
   fcntl(S->in_fd,F_GETFL,&val);
-  if (S->Flags & SF_NONBLOCK) val |= O_NONBLOCK;
+  if (S->Flags & STREAM_NONBLOCK) val |= O_NONBLOCK;
   else val &= (~O_NONBLOCK);
   fcntl(S->in_fd, F_SETFL, val);
 }
@@ -121,7 +121,7 @@ void STREAMResizeBuffer(STREAM *S, int size)
 	int PageSize;
 
 	PageSize=getpagesize();
-	if (S->Flags & SF_SECURE) S->BuffSize=(size / PageSize + 1) * PageSize;
+	if (S->Flags & STREAM_SECURE) S->BuffSize=(size / PageSize + 1) * PageSize;
   else S->BuffSize=size;
 
 	S->InputBuff =(char *) realloc(S->InputBuff,S->BuffSize);
@@ -131,7 +131,7 @@ void STREAMResizeBuffer(STREAM *S, int size)
 	if (S->InEnd > S->BuffSize) S->InEnd=0;
 	if (S->OutEnd > S->BuffSize) S->OutEnd=0;
 
-	if (S->Flags & SF_SECURE) 
+	if (S->Flags & STREAM_SECURE) 
 	{
 		mlock(S->InputBuff, S->BuffSize);
 		mlock(S->OutputBuff, S->BuffSize);
@@ -151,7 +151,7 @@ struct stat Stat;
   if (S->InEnd > S->InStart) return(TRUE);
   if (S->in_fd==-1) return(FALSE);
 
-	if (S->Flags & SF_FOLLOW) 
+	if (S->Flags & STREAM_FOLLOW) 
 	{
 		while (1)
 		{
@@ -262,7 +262,7 @@ if (S->out_fd==-1) return(STREAM_CLOSED);
 
 while (count < DataLen)
 {
-if (S->Flags & SF_SSL)
+if (S->Flags & STREAM_SSL)
 {
 #ifdef HAVE_LIBSSL
 result=SSL_write((SSL *) STREAMGetItem(S,"LIBUSEFUL-SSL-CTX"), Data + count, DataLen - count);
@@ -283,11 +283,11 @@ else
 		if (result == 0) return(STREAM_TIMEOUT);
 	}
 
-	if (S->Flags & SF_WRLOCK) flock(S->out_fd,LOCK_EX);
+	if (S->Flags & STREAM_WRLOCK) flock(S->out_fd,LOCK_EX);
 	if (S->BlockSize && (S->BlockSize < (DataLen-count))) result=S->BlockSize;
 	else result=DataLen-count;
   result=write(S->out_fd, Data + count, result);
-	if (S->Flags & SF_WRLOCK) flock(S->out_fd,LOCK_UN);
+	if (S->Flags & STREAM_WRLOCK) flock(S->out_fd,LOCK_UN);
 
 }
 
@@ -461,11 +461,11 @@ int fd, Mode=0;
 STREAM *Stream;
 struct stat myStat;
 
-if (Flags & SF_WRONLY) Mode=O_WRONLY;
-else if (Flags & SF_RDONLY) Mode=O_RDONLY;
+if (Flags & STREAM_WRONLY) Mode=O_WRONLY;
+else if (Flags & STREAM_RDONLY) Mode=O_RDONLY;
 else Mode=O_RDWR;
 
-if (Flags & SF_CREATE) Flags |= O_CREAT;
+if (Flags & STREAM_CREATE) Flags |= O_CREAT;
 
 if (strcmp(FilePath,"-")==0)
 {
@@ -477,7 +477,7 @@ return(Stream);
 fd=open(FilePath, Mode, 0600);
 if (fd==-1) return(NULL);
 
-if (Flags & SF_WRLOCK)
+if (Flags & STREAM_WRLOCK)
 {
 	if (flock(fd,LOCK_EX | LOCK_NB)==-1)
 	{
@@ -487,7 +487,7 @@ if (Flags & SF_WRLOCK)
 
 }
 
-if (Flags & SF_RDLOCK)
+if (Flags & STREAM_RDLOCK)
 {
 	if (flock(fd,LOCK_SH | LOCK_NB)==-1)
 	{
@@ -503,7 +503,7 @@ if (Flags & SF_RDLOCK)
 // to get us to write somewhere other than intended.
 
 
-if (! (Flags & SF_SYMLINK_OK))
+if (! (Flags & STREAM_SYMLINK_OK))
 {
 	if (lstat(FilePath, &myStat) !=0)
 	{
@@ -519,8 +519,8 @@ if (! (Flags & SF_SYMLINK_OK))
 	}
 }
 
-if (Flags & SF_TRUNC) ftruncate(fd,0);
-if (Flags & SF_APPEND) lseek(fd,0,SEEK_END);
+if (Flags & STREAM_TRUNC) ftruncate(fd,0);
+if (Flags & STREAM_APPEND) lseek(fd,0,SEEK_END);
 
 Stream=STREAMFromFD(fd);
 Stream->Path=CopyStr(Stream->Path,FilePath);
@@ -556,7 +556,7 @@ if (strncmp(Curr->Tag,"HelperPID",9)==0) kill(atoi(Curr->Item),SIGKILL);
 Curr=ListGetNext(Curr);
 }
 
-if (S->Flags & SF_SECURE) 
+if (S->Flags & STREAM_SECURE) 
 {
 	munlock(S->InputBuff, S->BuffSize);
 	munlock(S->OutputBuff, S->BuffSize);
@@ -634,14 +634,14 @@ SSL_CTX=STREAMGetItem(S,"LIBUSEFUL-SSL-CTX");
 //if there are bytes available in the internal OpenSSL buffers, when we don't have to 
 //wait on a select, we can just go straight through to SSL_read
 #ifdef HAVE_LIBSSL
-if (S->Flags & SF_SSL)
+if (S->Flags & STREAM_SSL)
 {
 if (SSL_pending((SSL *) SSL_CTX) > 0) WaitForBytes=FALSE;
 }
 #endif
 
 
-//if ((S->Timeout > 0) && (! (S->Flags & SF_NONBLOCK)) && WaitForBytes)
+//if ((S->Timeout > 0) && (! (S->Flags & STREAM_NONBLOCK)) && WaitForBytes)
 if ((S->Timeout > 0) && WaitForBytes)
 {
    FD_ZERO(&selectset);
@@ -681,16 +681,16 @@ if (read_result==0)
 	tmpBuff=SetStrLen(tmpBuff,S->BuffSize-S->InEnd);
 
 	#ifdef HAVE_LIBSSL
-	if (S->Flags & SF_SSL)
+	if (S->Flags & STREAM_SSL)
 	{
 		read_result=SSL_read((SSL *) SSL_CTX, tmpBuff, S->BuffSize-S->InEnd);
 	}
 	else
 	#endif
 	{
-		if (S->Flags & SF_RDLOCK) flock(S->in_fd,LOCK_SH);
+		if (S->Flags & STREAM_RDLOCK) flock(S->in_fd,LOCK_SH);
 		read_result=read(S->in_fd, tmpBuff, S->BuffSize-S->InEnd);
-		if (S->Flags & SF_RDLOCK) flock(S->in_fd,LOCK_UN);
+		if (S->Flags & STREAM_RDLOCK) flock(S->in_fd,LOCK_UN);
 	}
 
 	if (read_result > 0) 
@@ -1277,8 +1277,8 @@ long val, len;
 //if we are not using ssl and not using processor modules, we can use 
 //kernel-level copy!
 if (
-			(! (In->Flags & SF_SSL)) && 
-			(! (Out->Flags & SF_SSL)) && 
+			(! (In->Flags & STREAM_SSL)) && 
+			(! (Out->Flags & STREAM_SSL)) && 
 			(ListSize(In->ProcessingModules)==0) && 
 			(ListSize(Out->ProcessingModules)==0)
 	) UseSendFile=TRUE;
diff --git a/libUseful-2.1/file.h b/libUseful-2.1/file.h
index 84abebd..eadddbc 100644
--- a/libUseful-2.1/file.h
+++ b/libUseful-2.1/file.h
@@ -39,21 +39,21 @@
 #define FLUSH_ALWAYS 4
 #define FLUSH_BUFFER 8
 
-#define SF_RDWR 0 //is the default
-#define SF_RDONLY 16
-#define SF_WRONLY 32
-#define SF_CREAT 64
-#define SF_CREATE 64
-#define SF_APPEND 128
-#define SF_TRUNC 256
-#define SF_SYMLINK_OK 512
-#define SF_WRLOCK 1024
-#define SF_RDLOCK 2048
-#define SF_FOLLOW 4096
-#define SF_SECURE 8192
-#define SF_NONBLOCK 16384
-#define SF_SSL 32768
-#define SF_AUTH 65536
+#define STREAM_RDWR 0 //is the default
+#define STREAM_RDONLY 16
+#define STREAM_WRONLY 32
+#define STREAM_CREAT 64
+#define STREAM_CREATE 64
+#define STREAM_APPEND 128
+#define STREAM_TRUNC 256
+#define STREAM_SYMLINK_OK 512
+#define STREAM_WRLOCK 1024
+#define STREAM_RDLOCK 2048
+#define STREAM_FOLLOW 4096
+#define STREAM_SECURE 8192
+#define STREAM_NONBLOCK 16384
+#define STREAM_SSL 32768
+#define STREAM_AUTH 65536
 
 
 
diff --git a/libUseful-2.1/openssl.c b/libUseful-2.1/openssl.c
index 1dfda73..f810f71 100644
--- a/libUseful-2.1/openssl.c
+++ b/libUseful-2.1/openssl.c
@@ -318,7 +318,7 @@ if (S)
 	ptr=LibUsefulGetValue("SSL-Permitted-Ciphers");
 	if (ptr) SSL_set_cipher_list(ssl, ptr);
   result=SSL_connect(ssl);
-  S->Flags|=SF_SSL;
+  S->Flags|=STREAM_SSL;
 
 	OpenSSLQueryCipher(S);
 	OpenSSLVerifyCertificate(S);
@@ -428,7 +428,7 @@ if (S)
 	  result=SSL_accept(ssl);
 		if (result == TRUE)
 		{
-	  S->Flags|=SF_SSL;
+	  S->Flags|=STREAM_SSL;
 		OpenSSLQueryCipher(S);
 		if (Flags & SSL_VERIFY_PEER) OpenSSLVerifyCertificate(S);
 		}
diff --git a/libUseful-2.1/pty.c b/libUseful-2.1/pty.c
index d997efa..792e767 100644
--- a/libUseful-2.1/pty.c
+++ b/libUseful-2.1/pty.c
@@ -105,7 +105,10 @@ tty_data.c_iflag |= IXON | IXOFF;
 tty_data.c_cc[VSTART]=old_tty_data->c_cc[VSTART];
 tty_data.c_cc[VSTOP]=old_tty_data->c_cc[VSTOP];
 }
+
+#ifdef CRTSCTS
 if (Flags & TTYFLAG_HARDWARE_FLOW) tty_data.c_cflag |=CRTSCTS;
+#endif
 
 // 'local' input flags
 tty_data.c_lflag=0;
@@ -133,6 +136,8 @@ else
 	tty_data.c_cc[VTIME]=0;
 }
 
+//Higher line speeds protected with #ifdef because not all
+//operating systems seem to have them
 if (LineSpeed > 0)
 {
 switch (LineSpeed)
@@ -142,28 +147,43 @@ case 4800: val=B4800; break;
 case 9600: val=B9600; break;
 case 19200: val=B19200; break;
 case 38400: val=B38400; break;
+#ifdef B57600
 case 57600: val=B57600; break;
+#endif
+
+#ifdef B115200
 case 115200: val=B115200; break;
+#endif
+
+#ifdef B230400
 case 230400: val=B230400; break;
+#endif
+
 #ifdef B460800
 case 460800: val=B460800; break;
 #endif
+
 #ifdef B500000
 case 500000: val=B500000; break;
 #endif
+
 #ifdef B1000000
 case 10000000: val=B1000000; break;
 #endif
+
 #ifdef B1152000
 case 1152000: val=B1152000; break;
 #endif
+
 #ifdef B2000000
 case 2000000: val=B2000000; break;
 #endif
+
 #ifdef B4000000
 case 4000000: val=B4000000; break;
 #endif
-default: val=B115200; break;
+
+default: val=B38400; break;
 }
 cfsetispeed(&tty_data,val);
 cfsetospeed(&tty_data,val);
@@ -180,10 +200,23 @@ DestroyString(Tempstr);
 
 int OpenTTY(char *devname, int LineSpeed, int Flags)
 {
-int tty;
+int tty, flags=O_RDWR | O_NOCTTY;
+
+
+if (Flags & TTYFLAG_NONBLOCK) 
+{
+	//O_NDELAY should be used only if nothing else available
+	//as O_NONBLOCK is more 'posixy'
+	#ifdef O_NDELAY
+	flags |= O_NDELAY;
+	#endif
+
+	#ifdef O_NONBLOCK
+	flags |= O_NONBLOCK;
+	#endif
+}
 
-if (Flags & TTYFLAG_NONBLOCK) tty=open(devname,O_RDWR | O_NOCTTY | O_NDELAY);
-else tty=open(devname,O_RDWR | O_NOCTTY);
+tty=open(devname, flags);
 
 if ( tty <0) return(-1);
 InitTTY(tty, LineSpeed, Flags);
diff --git a/libUseful-2.1/socket.c b/libUseful-2.1/socket.c
index 0c54bcd..8458f7e 100644
--- a/libUseful-2.1/socket.c
+++ b/libUseful-2.1/socket.c
@@ -244,40 +244,6 @@ return(-1);
 #endif
 
 
-int InitUnixServerSock(int Type, const char *Path)
-{
-int sock;
-struct sockaddr_un sa;
-socklen_t salen;
-int result;
-
-if (Type==0) Type=SOCK_STREAM;
-sock=socket(AF_UNIX, Type, 0);
-if (sock <0) return(-1);
-
-//No reason to pass server/listen sockets across an exec
-fcntl(sock, F_SETFD, FD_CLOEXEC);
-
-result=1;
-salen=sizeof(result);
-strcpy(sa.sun_path,Path);
-sa.sun_family=AF_UNIX;
-salen=sizeof(struct sockaddr_un);
-result=bind(sock,(struct sockaddr *) &sa, salen);
-
-if ((result==0) && (Type==SOCK_STREAM))
-{
- result=listen(sock,10);
-}
-
-if (result==0) return(sock);
-else 
-{
-close(sock);
-return(-1);
-}
-}
-
 
 int TCPServerSockAccept(int ServerSock, char **Addr)
 {
@@ -296,20 +262,6 @@ return(sock);
 }
 
 
-int UnixServerSockAccept(int ServerSock)
-{
-struct sockaddr_un sa;
-socklen_t salen;
-int sock;
-
-salen=sizeof(sa);
-sock=accept(ServerSock,(struct sockaddr *) &sa,&salen);
-return(sock);
-}
-
-
-
-
 
 
 
@@ -652,7 +604,7 @@ if ((S->in_fd > -1) && (S->Timeout > 0) )
     S->in_fd=-1;
     S->out_fd=-1;
   }
-  else if (! (Flags & CONNECT_NONBLOCK))  STREAMSetFlags(S, 0, SF_NONBLOCK);
+  else if (! (Flags & CONNECT_NONBLOCK))  STREAMSetFlags(S, 0, STREAM_NONBLOCK);
 }
 
 if (S->in_fd > -1)
@@ -707,7 +659,7 @@ Curr=ListGetNext(Curr);
 //just connect to host
 if ((HopNo==0) && StrLen(DesiredHost))
 {
-	if (Flags & CONNECT_NONBLOCK) S->Flags |= SF_NONBLOCK;
+	if (Flags & CONNECT_NONBLOCK) S->Flags |= STREAM_NONBLOCK;
 	val=Flags;
 
 	//STREAMDoPostConnect handles this	
@@ -724,7 +676,7 @@ if (result==TRUE)
 	if (Flags & CONNECT_NONBLOCK) 
 	{
 		S->State |=SS_CONNECTING;
-		S->Flags |=SF_NONBLOCK;
+		S->Flags |=STREAM_NONBLOCK;
 	}
 	else
 	{
diff --git a/libUseful-2.1/socket.h b/libUseful-2.1/socket.h
index 05cda11..ad42fd7 100644
--- a/libUseful-2.1/socket.h
+++ b/libUseful-2.1/socket.h
@@ -2,6 +2,7 @@
 #define LIBUSEFUL_SOCK
 
 #include "includes.h"
+#include "limits.h"
 
 #define CONNECT_NONBLOCK 1
 #define CONNECT_SSL 2
@@ -11,6 +12,10 @@
 #define SOCK_CONNECTED 1
 #define SOCK_CONNECTING -1
 
+#ifndef HOST_NAME_MAX
+#define HOST_NAME_MAX 255
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -24,9 +29,7 @@ const char *GetInterfaceIP(const char *Interface);
 
 /* Server Socket Funcs*/
 int InitServerSock(int Type, const char *Address, int Port);
-int InitUnixServerSock(int Type, const char *Path);
 int TCPServerSockAccept(int ServerSock,char **Addr);
-int UnixServerSockAccept(int ServerSock);
 
 int GetSockDetails(int fd, char **LocalAddress, int *LocalPort, char **RemoteAddress, int *RemotePort);
 
diff --git a/libUseful-2.1/sound.c b/libUseful-2.1/sound.c
index 13f89a7..9633938 100644
--- a/libUseful-2.1/sound.c
+++ b/libUseful-2.1/sound.c
@@ -187,7 +187,7 @@ TAudioInfo *AudioInfo=NULL;
 char *FourCharacter;
 STREAM *S;
 
-S=STREAMOpenFile(FilePath,SF_RDONLY);
+S=STREAMOpenFile(FilePath,STREAM_RDONLY);
 if (! S) return(NULL);
 
 FourCharacter=calloc(4, sizeof(char));
diff --git a/libUseful-2.1/string.c b/libUseful-2.1/string.c
index 1ff0fc1..fc63d48 100644
--- a/libUseful-2.1/string.c
+++ b/libUseful-2.1/string.c
@@ -100,8 +100,16 @@ len+=StrLen(sptr)+1;
 len=len*2;
 
 
-ptr=(char *) realloc(ptr,len);
-if (ptr && sptr) strcat(ptr,sptr);
+ptr=(char *)realloc(ptr,len+1);
+if (ptr && sptr) 
+{
+	#ifdef strlcat
+	strlcat(ptr,sptr,len);
+	#else
+	strncat(ptr,sptr,len);
+	ptr[len]='\0';
+	#endif
+}
 }
 
 return(ptr);
@@ -152,10 +160,17 @@ else
 
 if (StrLen(Src)==0) return(ptr);
 len+=StrLen(Src);
-len++;
 
-ptr=(char *)realloc(ptr,len);
-if (ptr && Src) strcat(ptr,Src);
+ptr=(char *)realloc(ptr,len+1);
+if (ptr && Src) 
+{
+	#ifdef strlcat
+	strlcat(ptr,Src,len);
+	#else
+	strncat(ptr,Src,len);
+	ptr[len]='\0';
+	#endif
+}
 return(ptr);
 }
 
diff --git a/libUseful-2.1/tar.c b/libUseful-2.1/tar.c
index 94177ac..37f6483 100644
--- a/libUseful-2.1/tar.c
+++ b/libUseful-2.1/tar.c
@@ -113,7 +113,7 @@ while (TarReadHeader(Tar, Vars))
 		else if (strcmp(ptr,"file")==0)
 		{
 			MakeDirPath(Path,0700);
-			S=STREAMOpenFile(Path,SF_WRONLY|SF_CREAT|SF_TRUNC);
+			S=STREAMOpenFile(Path,STREAM_WRONLY|STREAM_CREAT|STREAM_TRUNC);
 			if (S) fchmod(S->out_fd,atoi(GetVar(Vars,"Mode")));
 			bytes_read=0;
 			bytes_total=atoi(GetVar(Vars,"Size"));
@@ -176,10 +176,10 @@ Head=(TTarHeader *) calloc(1,sizeof(TTarHeader));
 	memcpy(Head->version,"00",2);
 
 	pwd=getpwuid(FStat->st_uid);
-	if (pwd) strcpy(Head->uname,pwd->pw_name);
+	if (pwd) strncpy(Head->uname,pwd->pw_name,32);
 
 	grp=getgrgid(FStat->st_gid);
-	if (grp) strcpy(Head->gname,grp->gr_name);
+	if (grp) strncpy(Head->gname,grp->gr_name,32);
 
 	if ( (Head->typeflag == '3') || (Head->typeflag == '4') ) 
 	{
@@ -262,7 +262,7 @@ for (i=0; i < Glob.gl_pathc; i++)
 	}
 	else 
 	{
-		S=STREAMOpenFile(Glob.gl_pathv[i],SF_RDONLY);
+		S=STREAMOpenFile(Glob.gl_pathv[i],STREAM_RDONLY);
 		if (S)
 		{
 			TarWriteHeader(Tar, Glob.gl_pathv[i],&FStat);
diff --git a/libUseful-2.1/unix_socket.c b/libUseful-2.1/unix_socket.c
index d24b4d9..e047a75 100644
--- a/libUseful-2.1/unix_socket.c
+++ b/libUseful-2.1/unix_socket.c
@@ -4,6 +4,85 @@
 #include <sys/un.h>
 
 
+// crazyshit function because different implementations treat 
+// sun_path differently, so we have to derive a safe length for it!
+void sun_set_path(struct sockaddr_un *sa, const char *Path)
+{
+int len, val;
+char *ptr1, *ptr2;
+off_t pos;
+
+ptr1=sa->sun_path;
+ptr2=sa; //sa is already a pointer, so we don't need &
+
+len=sizeof(struct sockaddr_un) - (ptr1-ptr2);
+
+if (len > 0)
+{
+	len--; //force room for terminating \0
+
+	//all hail strlcpy, makes life easier
+	#ifdef strlcpy
+	strlcpy(sa.sun_path,Path,len);
+
+	//else grrrr
+	#else
+	val=strlen(Path);
+	if (val < len) len=val;
+	strncpy(sa->sun_path,Path,len);
+	sa->sun_path[len]='\0';
+	#endif
+}
+
+}
+
+
+int InitUnixServerSock(int Type, const char *Path)
+{
+int sock;
+struct sockaddr_un sa;
+socklen_t salen;
+int result;
+
+if (Type==0) Type=SOCK_STREAM;
+sock=socket(AF_UNIX, Type, 0);
+if (sock <0) return(-1);
+
+//No reason to pass server/listen sockets across an exec
+fcntl(sock, F_SETFD, FD_CLOEXEC);
+
+sa.sun_family=AF_UNIX;
+salen=sizeof(struct sockaddr_un);
+sun_set_path(&sa, Path);
+result=bind(sock,(struct sockaddr *) &sa, salen);
+
+if ((result==0) && (Type==SOCK_STREAM))
+{
+ result=listen(sock,10);
+}
+
+if (result==0) return(sock);
+else 
+{
+close(sock);
+return(-1);
+}
+}
+
+
+
+int UnixServerSockAccept(int ServerSock)
+{
+struct sockaddr_un sa;
+socklen_t salen;
+int sock;
+
+salen=sizeof(sa);
+sock=accept(ServerSock,(struct sockaddr *) &sa,&salen);
+return(sock);
+}
+
+
 int OpenUnixSocket(const char *Path, int Type)
 {
 int sock;
@@ -18,7 +97,7 @@ if (sock==-1) return(-1);
 
 memset(&sa,0,sizeof(struct sockaddr_un));
 sa.sun_family=AF_UNIX;
-strcpy(sa.sun_path,Path);
+sun_set_path(&sa, Path);
 val=sizeof(sa);
 if (connect(sock,(struct sockaddr *) &sa,val)==0) return(sock);
 
diff --git a/libUseful-2.1/unix_socket.h b/libUseful-2.1/unix_socket.h
index 8850fe4..484ee99 100644
--- a/libUseful-2.1/unix_socket.h
+++ b/libUseful-2.1/unix_socket.h
@@ -9,7 +9,8 @@
 extern "C" {
 #endif
 
-
+int InitUnixServerSock(int Type, const char *Path);
+int UnixServerSockAccept(int ServerSock);
 int OpenUnixSocket(const char *Path, int SockType);
 int STREAMConnectUnixSocket(STREAM *S, const char *Path, int SockType);
 
diff --git a/main.c b/main.c
index 0027c9f..6d6e628 100644
--- a/main.c
+++ b/main.c
@@ -16,7 +16,7 @@ STREAM *S;
 struct stat Stat;
 
 if (strcmp(Ctx->ListPath,"-")==0) S=STREAMFromFD(0);
-else S=STREAMOpenFile(Ctx->ListPath,SF_RDONLY);
+else S=STREAMOpenFile(Ctx->ListPath,STREAM_RDONLY);
 Tempstr=STREAMReadLine(Tempstr, S);
 while (Tempstr)
 {
@@ -42,6 +42,24 @@ DestroyString(HashStr);
 }
 
 
+void HashStdInOutput(HashratCtx *Ctx, const char *Hash)
+{
+char *Tempstr=NULL, *Base64=NULL;
+
+	Tempstr=MCopyStr(Tempstr,Hash,"\n",NULL);
+	STREAMWriteString(Tempstr,Ctx->Out); 
+
+	if (Flags & FLAG_XSELECT)
+	{
+	Base64=EncodeBytes(Base64, Hash, StrLen(Hash), ENCODE_BASE64);
+	Tempstr=FormatStr(Tempstr,"\x1b]52;cps;%s\x07",Base64);
+	STREAMWriteString(Tempstr,Ctx->Out);
+	}
+
+DestroyString(Tempstr);
+DestroyString(Base64);
+}
+
 
 
 void HashStdIn(HashratCtx *Ctx)
@@ -62,7 +80,8 @@ if (Flags & FLAG_LINEMODE)
 		if (! (Flags & FLAG_RAW)) StripTrailingWhitespace(Tempstr);
 		Hash=CopyStr(Hash,"");
 		ProcessData(&Hash, Ctx, Tempstr, StrLen(Tempstr));
-		STREAMWriteString(Hash,Ctx->Out); STREAMWriteString("\n",Ctx->Out);
+		HashStdInOutput(Ctx, Hash);
+
 		if (Flags & FLAG_HIDE_INPUT) Tempstr=TTYReadSecret(Tempstr, In, 0);
 		else if (Flags & FLAG_STAR_INPUT) Tempstr=TTYReadSecret(Tempstr, In, TEXT_STARS);
 		else Tempstr=STREAMReadLine(Tempstr,In);
@@ -71,7 +90,7 @@ if (Flags & FLAG_LINEMODE)
 else
 {
 	HashratHashSingleFile(Ctx, Ctx->HashType, 0, "-", NULL, &Hash);
-	STREAMWriteString(Hash,Ctx->Out); STREAMWriteString("\n",Ctx->Out);
+	HashStdInOutput(Ctx, Hash);
 }
 STREAMDisassociateFromFD(In);
 
diff --git a/xattr.c b/xattr.c
index bd7de4c..abf5f29 100644
--- a/xattr.c
+++ b/xattr.c
@@ -6,6 +6,11 @@
  #include <sys/xattr.h>
 #endif
 
+#ifdef USE_EXTATTR
+ #include <sys/types.h>
+ #include <sys/extattr.h>
+#endif
+
 
 
 char **XAttrList=NULL;
@@ -47,34 +52,46 @@ DestroyString(Token);
 
 void HashRatSetXAttr(HashratCtx *Ctx, char *Path, struct stat *Stat, char *HashType, char *Hash)
 {
-#ifdef USE_XATTR
 char *Tempstr=NULL, *Attr=NULL;
 char **ptr;
 int result;
 
+	Tempstr=FormatStr(Tempstr,"%lu:%llu:%s",(unsigned long) time(NULL),(unsigned long long) Stat->st_size,Hash);
+
+
+#ifdef USE_XATTR
 	if ((Ctx->Flags & CTX_XATTR_ROOT) && (getuid()==0)) Attr=MCopyStr(Attr,"trusted.","hashrat:",HashType,NULL);
 	else Attr=MCopyStr(Attr,"user.","hashrat:",HashType,NULL);
-	Tempstr=FormatStr(Tempstr,"%lu:%llu:%s",(unsigned long) time(NULL),(unsigned long long) Stat->st_size,Hash);
-	result=setxattr(Path, Attr, Tempstr, StrLen(Tempstr)+1, 0);
 
+	result=setxattr(Path, Attr, Tempstr, StrLen(Tempstr)+1, 0);
 	if (result != 0) fprintf(stderr,"ERROR: Failed to store hash in extended attributes for %s\n", Path);
+#elif defined USE_EXTATTR
+	Attr=MCopyStr(Attr,"hashrat:",HashType,NULL);
+	if ((Ctx->Flags & CTX_XATTR_ROOT) && (getuid()==0)) result=extattr_set_file(Path, EXTATTR_NAMESPACE_SYSTEM, Attr, Tempstr, StrLen(Tempstr)+1);
+	else result=extattr_set_file(Path, EXTATTR_NAMESPACE_USER, Attr, Tempstr, StrLen(Tempstr)+1);
+	if (result < 1) fprintf(stderr,"ERROR: Failed to store hash in extended attributes for %s\n", Path);
+#else
+	fprintf(stderr,"XATTR Support not compiled in.\n");
+	exit(1);
+#endif
+
+
 
 	if (XAttrList)
 	{
 		for(ptr=XAttrList; *ptr !=NULL; ptr++)
 		{
+#ifdef USE_XATTR
 		setxattr(Path, *ptr, Hash, StrLen(Hash), 0);
+#elif defined USE_EXTATTR
+		extattr_set_file(Path, EXTATTR_NAMESPACE_USER, Attr, Tempstr, StrLen(Tempstr)+1);
+#endif
 		}
 	}
 
 DestroyString(Tempstr);
 DestroyString(Attr);
 
-#else
-fprintf(stderr,"XATTR Support not compiled in.\n");
-exit(1);
-
-#endif
 }
 
 
@@ -82,14 +99,19 @@ int XAttrGetHash(HashratCtx *Ctx, char *XattrType, char *HashType, char *Path, s
 {
 int result=FALSE;
 
-#ifdef USE_XATTR
 char *Tempstr=NULL, *ptr;
 int len;
 
-
-Tempstr=MCopyStr(Tempstr,XattrType, ".hashrat:",HashType,NULL);
 *Hash=SetStrLen(*Hash,255);
+#ifdef USE_XATTR
+Tempstr=MCopyStr(Tempstr,XattrType, ".hashrat:",HashType,NULL);
 len=getxattr(Path, Tempstr, *Hash, 255); 
+#elif defined USE_EXTATTR
+Tempstr=MCopyStr(Tempstr,"hashrat:",HashType,NULL);
+if ((strcmp(XattrType,"trusted")==0) || (strcmp(XattrType,"system")==0)) len=extattr_get_file(Path, EXTATTR_NAMESPACE_SYSTEM, Tempstr, *Hash, 255);
+else len=extattr_get_file(Path, EXTATTR_NAMESPACE_USER, Tempstr, *Hash, 255);
+#endif
+
 if (len > 0)
 {
 	(*Hash)[len]='\0';
@@ -104,7 +126,6 @@ if (len > 0)
 }
 
 DestroyString(Tempstr);
-#endif
 
 return(result);
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/hashrat.git



More information about the forensics-changes mailing list