lots of uncommitted junkcode
authortridge <>
Thu, 15 Jan 2004 16:52:51 +0000 (16:52 +0000)
committertridge <>
Thu, 15 Jan 2004 16:52:51 +0000 (16:52 +0000)
43 files changed:
getmntent.c [new file with mode: 0644]
getpwnam.c [new file with mode: 0644]
getpwuid.c [new file with mode: 0644]
hextobin.c [new file with mode: 0644]
histogram.awk [new file with mode: 0644]
kverify.c [new file with mode: 0644]
locker.c [new file with mode: 0644]
longdate.c [new file with mode: 0644]
malloc_speed.c [new file with mode: 0644]
malloc_zero.c [new file with mode: 0644]
matching_bits.c [new file with mode: 0644]
memfind.c [new file with mode: 0644]
mksparse.c [new file with mode: 0644]
mmap_check.c [new file with mode: 0644]
myupdate.c [new file with mode: 0644]
name.c [new file with mode: 0644]
notify.c [new file with mode: 0644]
ntstatus.c [new file with mode: 0644]
permute.c [new file with mode: 0644]
pes_parse.c [new file with mode: 0644]
rand_syscall.c [new file with mode: 0644]
readloop.c [new file with mode: 0644]
rename_loop.c [new file with mode: 0644]
rline/rline.c
rproxy/signature.c
rtime2.c [new file with mode: 0644]
sendfile.c [new file with mode: 0644]
serialbug.c [new file with mode: 0644]
sleeptst.c [new file with mode: 0644]
snc.c [new file with mode: 0644]
sock_exec.c [new file with mode: 0644]
sockspy-rpc.c [new file with mode: 0644]
stack.c [new file with mode: 0644]
stringize.c [new file with mode: 0644]
sysconf.c [new file with mode: 0644]
time_speed.c [new file with mode: 0644]
timing_attack.c [new file with mode: 0644]
tprog.c [new file with mode: 0644]
tstid.c [new file with mode: 0644]
udpspy.c [new file with mode: 0644]
usleep.c [new file with mode: 0644]
werror.c [new file with mode: 0644]
xkeys.c [new file with mode: 0644]

diff --git a/getmntent.c b/getmntent.c
new file mode 100644 (file)
index 0000000..6f945af
--- /dev/null
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <mntent.h>
+
+int main(void)
+{
+       FILE *f = setmntent("/etc/mtab", "r");
+       struct mntent *m;
+
+       while ((m = getmntent(f))) {
+               printf("%s %s %s\n", 
+                      m->mnt_fsname, m->mnt_dir, m->mnt_type);
+       }
+       
+       endmntent(f);
+       return 0;
+}
+
diff --git a/getpwnam.c b/getpwnam.c
new file mode 100644 (file)
index 0000000..921fc9a
--- /dev/null
@@ -0,0 +1,7 @@
+
+main()
+{
+       getpwnam("root");
+       getpwnam("root");
+       getpwnam("root");
+}
diff --git a/getpwuid.c b/getpwuid.c
new file mode 100644 (file)
index 0000000..7ec1097
--- /dev/null
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <pwd.h>
+#include <sys/types.h>
+
+static void print_passwd(struct passwd *pwd)
+{
+       printf("%s:%s:%d:%d:%s:%s:%s\n", 
+              pwd->pw_name,
+              pwd->pw_passwd,
+              pwd->pw_uid,
+              pwd->pw_gid,
+              pwd->pw_gecos,
+              pwd->pw_dir,
+              pwd->pw_shell);
+}
+
+int main(int argc, char *argv[])
+{
+       struct passwd *pwd;
+
+       pwd = getpwuid(atoi(argv[1]));
+
+       if (!pwd) {
+               printf("Failed to fetch pwd\n");
+       } else {
+               print_passwd(pwd);
+       }
+       return 0;
+}
diff --git a/hextobin.c b/hextobin.c
new file mode 100644 (file)
index 0000000..e48559f
--- /dev/null
@@ -0,0 +1,13 @@
+/* convert a hex stream to a file.
+   useful for reversing tcpdump or nc captures
+*/
+#include <stdio.h>
+
+int main(void)
+{
+       int c;
+       while (scanf("%2x", &c) == 1) {
+               fputc(c, stdout);
+       }
+       return 0;
+}
diff --git a/histogram.awk b/histogram.awk
new file mode 100644 (file)
index 0000000..e1e1ebc
--- /dev/null
@@ -0,0 +1,11 @@
+
+{
+  counts[$1]++;
+  total++;
+}
+
+END {
+  for (v in counts) {
+    printf "%d (%.0f%%) %s\n", counts[v], (100*counts[v])/total, v;
+  }
+}
diff --git a/kverify.c b/kverify.c
new file mode 100644 (file)
index 0000000..d3b02b7
--- /dev/null
+++ b/kverify.c
@@ -0,0 +1,170 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <krb5.h>
+
+#define DEBUG(l, x) printf x
+#define NT_STATUS_LOGON_FAILURE -1
+#define NT_STATUS_NO_MEMORY -1
+#define NT_STATUS_OK 0
+
+/****************************************************************************
+load a file into memory from a fd.
+****************************************************************************/ 
+
+char *fd_load(int fd, size_t *size)
+{
+       struct stat sbuf;
+       char *p;
+
+       if (fstat(fd, &sbuf) != 0) return NULL;
+
+       p = (char *)malloc(sbuf.st_size+1);
+       if (!p) return NULL;
+
+       if (read(fd, p, sbuf.st_size) != sbuf.st_size) {
+               free(p);
+               return NULL;
+       }
+       p[sbuf.st_size] = 0;
+
+       if (size) *size = sbuf.st_size;
+
+       return p;
+}
+
+/****************************************************************************
+load a file into memory
+****************************************************************************/
+char *file_load(const char *fname, size_t *size)
+{
+       int fd;
+       char *p;
+
+       if (!fname || !*fname) return NULL;
+       
+       fd = open(fname,O_RDONLY);
+       if (fd == -1) return NULL;
+
+       p = fd_load(fd, size);
+
+       close(fd);
+
+       return p;
+}
+
+/*
+  verify an incoming ticket and parse out the principal name and 
+  authorization_data if available 
+*/
+static int verify_ticket(const char *ticket, size_t tsize, char *password_s)
+{
+       krb5_context context;
+       krb5_auth_context auth_context = NULL;
+       krb5_keytab keytab = NULL;
+       krb5_data packet;
+       krb5_ticket *tkt = NULL;
+       krb5_data salt;
+       krb5_encrypt_block eblock;
+       int ret, i;
+       krb5_keyblock * key;
+       krb5_principal host_princ;
+       char *host_princ_s;
+       char *myname = "blu";
+       char *realm = "FLAGSHIP.DOT-NET";
+       krb5_data password;
+       krb5_enctype *enctypes = NULL;
+
+       password.data = password_s;
+       password.length = strlen(password_s);
+
+       ret = krb5_init_context(&context);
+       if (ret) {
+               DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret)));
+               return -1;
+       }
+
+       ret = krb5_set_default_realm(context, realm);
+       if (ret) {
+               DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret)));
+               return -1;
+       }
+
+       /* this whole process is far more complex than I would
+           like. We have to go through all this to allow us to store
+           the secret internally, instead of using /etc/krb5.keytab */
+       ret = krb5_auth_con_init(context, &auth_context);
+       if (ret) {
+               DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret)));
+               return -1;
+       }
+
+       asprintf(&host_princ_s, "HOST/%s@%s", myname, realm);
+       ret = krb5_parse_name(context, host_princ_s, &host_princ);
+       if (ret) {
+               DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret)));
+               return -1;
+       }
+
+       ret = krb5_principal2salt(context, host_princ, &salt);
+       if (ret) {
+               DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret)));
+               return NT_STATUS_LOGON_FAILURE;
+       }
+    
+       if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if ((ret = krb5_get_permitted_enctypes(context, &enctypes))) {
+               DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n", 
+                        error_message(ret)));
+               return NT_STATUS_LOGON_FAILURE;
+       }
+
+       for (i=0;enctypes[i];i++) {
+               krb5_use_enctype(context, &eblock, enctypes[i]);
+
+               ret = krb5_string_to_key(context, &eblock, key, &password, &salt);
+               if (ret) {
+                       continue;
+               }
+
+               krb5_auth_con_setuseruserkey(context, auth_context, key);
+
+               packet.length = tsize;
+               packet.data = (krb5_pointer)ticket;
+
+               if (!(ret = krb5_rd_req(context, &auth_context, &packet, 
+                                      NULL, keytab, NULL, &tkt))) {
+                       krb5_free_ktypes(context, enctypes);
+                       return NT_STATUS_OK;
+               }
+       }
+
+       DEBUG(1,("krb5_rd_req failed (%s)\n", 
+                error_message(ret)));
+
+       krb5_free_ktypes(context, enctypes);
+
+       return NT_STATUS_LOGON_FAILURE;
+}
+
+
+int main(int argc, char *argv[])
+{
+       char *tfile = argv[1];
+       char *pass = argv[2];
+       char *ticket;
+       size_t tsize;
+
+       ticket = file_load(tfile, &tsize);
+       if (!ticket) {
+               perror(tfile);
+               exit(1);
+       }
+       
+       return verify_ticket(ticket, tsize, pass);
+}
diff --git a/locker.c b/locker.c
new file mode 100644 (file)
index 0000000..5170d38
--- /dev/null
+++ b/locker.c
@@ -0,0 +1,99 @@
+/*
+  a simple demonsration of a scaling problem in byte range locks on solaris
+
+  try this as 'locker 800 1' and compare to 'locker 800 0'
+
+  tridge@samba.org, July 2002
+*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+static int brlock(int fd, off_t offset, int rw_type, int lck_type)
+{
+       struct flock fl;
+       int ret;
+
+       fl.l_type = rw_type;
+       fl.l_whence = SEEK_SET;
+       fl.l_start = offset;
+       fl.l_len = 1;
+       fl.l_pid = 0;
+
+       ret = fcntl(fd,lck_type,&fl);
+
+       if (ret == -1) {
+               printf("brlock failed offset=%d rw_type=%d lck_type=%d : %s\n", 
+                      (int)offset, rw_type, lck_type, strerror(errno));
+       }
+       return 0;
+}
+
+static void slave(int fd, int nlocks)
+{
+       int i;
+       for (i=1; i<nlocks+1; i++) {
+               brlock(fd, i, F_RDLCK, F_SETLKW);
+               usleep(1); /* essentially just a yield() */
+       }
+
+       /* this last lock will block until the master unlocks it */
+       brlock(fd, 0, F_WRLCK, F_SETLKW);
+       brlock(fd, 0, F_UNLCK, F_SETLKW);
+}
+
+int main(int argc, char *argv[])
+{
+       int i, fd;
+       int nproc, nlocks;
+       const char *fname = "locker.dat";
+       char c;
+
+       if (argc < 3) {
+               printf("Usage: locker <nproc> <nlocks>\n");
+               exit(1);
+       }
+
+       nproc = atoi(argv[1]);
+       nlocks = atoi(argv[2]);
+       setpgrp();
+
+       fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0600);
+       if (fd == -1) {
+               perror(fname);
+               exit(1);
+       }
+
+       /* set the master lock - this stops the children exiting */
+       brlock(fd, 0, F_WRLCK, F_SETLKW);
+
+       for (i=0;i<nproc;i++) {
+               switch (fork()) {
+               case 0:
+                       slave(fd, nlocks);
+                       exit(0);
+               case -1:
+                       perror("fork");
+                       kill(0, SIGTERM);
+                       exit(1);
+               }
+       }
+
+       printf("hit enter to continue\n");
+       read(0, &c, 1);
+
+       printf("unlocking ....\n");
+       brlock(fd, 0, F_UNLCK, F_SETLKW);
+
+       while (waitpid(0, NULL, 0) > 0 || errno != ECHILD) /* noop */ ;
+
+       printf("done\n");
+
+       return 0;
+}
diff --git a/longdate.c b/longdate.c
new file mode 100644 (file)
index 0000000..2bcdb51
--- /dev/null
@@ -0,0 +1,76 @@
+#define TIME_FIXUP_CONSTANT1 (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
+#define TIME_FIXUP_CONSTANT2 (TIME_FIXUP_CONSTANT1)
+
+/****************************************************************************
+interpret an 8 byte "filetime" structure to a time_t
+It's originally in "100ns units since jan 1st 1601"
+
+It appears to be kludge-GMT (at least for file listings). This means
+its the GMT you get by taking a localtime and adding the
+serverzone. This is NOT the same as GMT in some cases. This routine
+converts this to real GMT.
+****************************************************************************/
+time_t interpret_long_date(char *p)
+{
+  double d;
+  time_t ret;
+  uint32 tlow,thigh;
+  tlow = IVAL(p,0);
+  thigh = IVAL(p,4);
+
+  if (thigh == 0) return(0);
+
+  d = ((double)thigh)*4.0*(double)(1<<30);
+  d += (tlow&0xFFF00000);
+  d *= 1.0e-7;
+  /* now adjust by 369 years to make the secs since 1970 */
+  d -= TIME_FIXUP_CONSTANT1;
+
+  if (!(TIME_T_MIN <= d && d <= TIME_T_MAX))
+    return(0);
+
+  ret = (time_t)(d+0.5);
+
+  /* this takes us from kludge-GMT to real GMT */
+  ret -= serverzone;
+  ret += LocTimeDiff(ret);
+
+  return(ret);
+}
+
+
+/****************************************************************************
+put a 8 byte filetime from a time_t
+This takes real GMT as input and converts to kludge-GMT
+****************************************************************************/
+void put_long_date(char *p,time_t t)
+{
+  uint32 tlow,thigh;
+  double d;
+
+  if (t==0) {
+    SIVAL(p,0,0); SIVAL(p,4,0);
+    return;
+  }
+
+  /* this converts GMT to kludge-GMT */
+  t -= LocTimeDiff(t) - serverzone; 
+
+  d = (double) (t);
+
+  d += TIME_FIXUP_CONSTANT2;
+
+  d *= 1.0e7;
+
+  thigh = (uint32)(d * (1.0/(4.0*(double)(1<<30))));
+  tlow = (uint32)(d - ((double)thigh)*4.0*(double)(1<<30));
+
+  SIVAL(p,0,tlow);
+  SIVAL(p,4,thigh);
+}
+
+int main(int argc, char *argv[])
+{
+
+}
diff --git a/malloc_speed.c b/malloc_speed.c
new file mode 100644 (file)
index 0000000..0b18c1b
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+       int i;
+       time_t t, t2;
+       int count = atoi(argv[1]);
+       int size = atoi(argv[2]);
+
+       t = time(NULL);
+
+       for (i=0;i<count; i++) {
+               char *p;
+               p = malloc(size);
+               if (!p) {
+                       printf("malloc failed!\n");
+                       exit(1);
+               }
+               free(p);
+       }
+
+       t2 = time(NULL);
+       
+       printf("%g ops/sec\n", (2.0*i) / (t2-t));
+       return 0;
+}
diff --git a/malloc_zero.c b/malloc_zero.c
new file mode 100644 (file)
index 0000000..94d0c66
--- /dev/null
@@ -0,0 +1,24 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+main()
+{
+       int s_a, s_b;
+       unsigned u_a, u_b;
+       size_t a, b;
+       size_t r;
+       s_a = u_a = a = (1<<30) + 5;
+       s_b = u_b = b = 5000;
+
+       r = s_a * s_b;
+       printf("r=%u\n", r);
+
+       r = u_a * s_b;
+       printf("r=%u\n", r);
+
+       r = s_a * u_b;
+       printf("r=%u\n", r);
+
+       r = u_a * u_b;
+       printf("r=%u\n", r);
+}
diff --git a/matching_bits.c b/matching_bits.c
new file mode 100644 (file)
index 0000000..70e3f54
--- /dev/null
@@ -0,0 +1,56 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <math.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <strings.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+typedef unsigned char uchar;
+
+/****************************************************************************
+return the number of bits that match between two 4 character buffers
+  ***************************************************************************/
+int matching_quad_bits(uchar *p1, uchar *p2)
+{
+       int i, j, ret = 0;
+       for (i=0; i<4; i++) {
+               if (p1[i] != p2[i]) break;
+               ret += 8;
+       }
+
+       if (i==4) return ret;
+
+       for (j=0; j<8; j++) {
+               if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break;
+               ret++;
+       }       
+       
+       return ret;
+}
+
+
+int main(int argc, char *argv[])
+{
+       struct in_addr ip1, ip2;
+
+       if (argc < 3) {
+               printf("Usage: matching_bits IP1 IP2\n");
+               exit(1);
+       }
+
+       inet_aton(argv[1], &ip1);
+       inet_aton(argv[2], &ip2);
+
+       printf("%d\n", matching_quad_bits((uchar *)&ip1.s_addr, (uchar *)&ip2.s_addr));
+       return 0;
+}
diff --git a/memfind.c b/memfind.c
new file mode 100644 (file)
index 0000000..b63f7a7
--- /dev/null
+++ b/memfind.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+static void *map_file(char *fname, size_t *size)
+{
+       int fd = open(fname, O_RDONLY);
+       struct stat st;
+       void *p;
+
+       fstat(fd, &st);
+       p = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+       close(fd);
+
+       *size = st.st_size;
+       return p;
+}
+
+int main(int argc, char *argv[])
+{
+       size_t size1, size2, ofs1=0;
+       char *p1, *p2;
+
+       p1 = map_file(argv[1], &size1);
+       p2 = map_file(argv[2], &size2);
+       
+       while (ofs1 < size1) {
+               int n = 32;
+               char *q, *p = memmem(p2, size2, p1+ofs1, 32);
+               if (!p) {
+                       printf("data at %d not found!\n", ofs1);
+                       exit(1);
+               }
+               
+               while (p[n] == p1[ofs1+n]) n++;
+               printf("found 0x%x bytes at 0x%x (to 0x%x)\n",
+                      n, (int)(p-p2), (int)(n+(p-p2)));
+               ofs1 += n;
+       }
+}
diff --git a/mksparse.c b/mksparse.c
new file mode 100644 (file)
index 0000000..4c9dab1
--- /dev/null
@@ -0,0 +1,16 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+int main(int argc, char *argv[])
+{
+       char *fname = argv[1];
+       off_t megs = atoi(argv[2]);
+       int fd;
+
+       fd = open(fname,O_WRONLY|O_CREAT|O_TRUNC, 0600);
+       lseek(fd, megs * 1024*1024, SEEK_SET);
+       write(fd, fname, strlen(fname));
+       close(fd);
+       return 0;
+}
diff --git a/mmap_check.c b/mmap_check.c
new file mode 100644 (file)
index 0000000..8ccd33b
--- /dev/null
@@ -0,0 +1,106 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+
+
+static pid_t child_pid;
+
+#define LENGTH (1<<20)
+#define FNAME "mmap.dat"
+
+static void child_main(int pfd)
+{
+       int fd;
+       char *map;
+
+       while ((fd = open(FNAME,O_RDWR)) == -1) sleep(1);
+
+       map = mmap(0, LENGTH, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FILE, fd, 0);
+
+       while (1) {
+               int ofs, len, ret;
+               int i;
+               char buf[64];
+
+               read(pfd, &ofs, sizeof(ofs));
+               read(pfd, &len, sizeof(len));
+
+               if (random() % 2) {
+                       memcpy(buf, map+ofs, len);
+               } else {
+                       pread(fd, buf, len, ofs);
+               }
+
+               for (i=0;i<len;i++) {
+                       if (buf[i] != (char)(ofs+len+i)) {
+                               printf("child failed\n");
+                               exit(1);
+                       }
+               }
+
+               ret = 0;
+               write(pfd, &ret, sizeof(ret));
+       }
+}
+
+       
+static void parent_main(int pfd)
+{
+       char *map;
+       int fd = open(FNAME,O_RDWR|O_CREAT|O_TRUNC, 0600);
+
+       ftruncate(fd, LENGTH);
+
+       map = mmap(0, LENGTH, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FILE, fd, 0);
+
+       while (1) {
+               int ofs, len, ret;
+               int i;
+               char buf[64];
+
+               ofs = random() % (LENGTH-64);
+               len = random() % 64;
+
+               for (i=0;i<len;i++) buf[i] = ofs+len+i;
+
+               if (random() % 2) {
+                       memcpy(map+ofs, buf, len);
+               } else {
+                       pwrite(fd, buf, len, ofs);
+               }
+
+               write(pfd, &ofs, sizeof(ofs));
+               write(pfd, &len, sizeof(len));
+
+               read(pfd, &ret, sizeof(ret));
+       }
+}
+
+
+
+int main()
+{
+       int pfd[2];
+
+       socketpair(AF_UNIX, SOCK_STREAM, 0, pfd);
+
+       srandom(getpid());
+
+       if ((child_pid=fork()) == 0) {
+               close(pfd[0]);
+               child_main(pfd[1]);
+       } else {
+               close(pfd[1]);
+               parent_main(pfd[0]);
+       }
+       return 0;
+}
diff --git a/myupdate.c b/myupdate.c
new file mode 100644 (file)
index 0000000..dcb6d13
--- /dev/null
@@ -0,0 +1,18 @@
+#include <unistd.h>
+#include <stdio.h>
+
+
+int main(int argc,char *argv[])
+{
+int delay = 30;
+if (argc>1)
+  delay = atoi(argv[1]);
+
+while (1)
+  {
+    sleep(delay);
+    sync();
+  }
+return(0);
+}
+
diff --git a/name.c b/name.c
new file mode 100644 (file)
index 0000000..7280c3f
--- /dev/null
+++ b/name.c
@@ -0,0 +1,36 @@
+#include <stdio.h>
+
+/****************************************************************************
+interpret the weird netbios "name"
+****************************************************************************/
+void name_interpret(char *in,char *out)
+{
+
+int len = (*in++) / 2;
+while (len--)
+  {
+    *out = ((in[0]-'A')<<4) + (in[1]-'A');
+    in += 2;
+    out++;
+  }
+*out = 0;
+/* Handle any scope names */
+while(*in) 
+  {
+  *out++ = '.'; /* Scope names are separated by periods */
+  len = *(unsigned char *)in++;
+  strncpy(out, in, len);
+  out += len;
+  *out=0;
+  in += len;
+  }
+}
+
+
+main(int argc,char *argv[])
+{
+  char out[100];
+
+  name_interpret(argv[1],out);
+  puts(out);
+}
diff --git a/notify.c b/notify.c
new file mode 100644 (file)
index 0000000..2088140
--- /dev/null
+++ b/notify.c
@@ -0,0 +1,44 @@
+#define DN_ACCESS       0x00000001      /* File accessed in directory */
+#define DN_MODIFY       0x00000002      /* File modified in directory */
+#define DN_CREATE       0x00000004      /* File created in directory */
+#define DN_DELETE       0x00000008      /* File removed from directory */
+#define DN_RENAME       0x00000010      /* File renamed in directory */
+#define DN_ATTRIB       0x00000020      /* File changed attribute */
+#define DN_MULTISHOT    0x80000000      /* Don't remove notifier */
+#define F_NOTIFY 1026
+
+#define _GNU_SOURCE    /* needed to get the defines */
+#include <fcntl.h>     /* in glibc 2.2 this has the needed
+                                  values defined */
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static int event_fd;
+
+static void handler(int sig, siginfo_t *si, void *data)
+{
+       event_fd = si->si_fd;
+}
+
+int main(void)
+{
+       struct sigaction act;
+       int fd;
+       
+       act.sa_sigaction = handler;
+       sigemptyset(&act.sa_mask);
+       act.sa_flags = SA_SIGINFO;
+       sigaction(SIGRTMIN, &act, NULL);
+       
+       fd = open(".", O_RDONLY);
+       fcntl(fd, F_SETSIG, SIGRTMIN);
+       fcntl(fd, F_NOTIFY, DN_MODIFY|DN_CREATE|DN_MULTISHOT);
+       /* we will now be notified if any of the files
+          in "dir" is modified or new files are
+          created */
+       while (1) {
+               pause();
+               printf("Got event on fd=%d\n", event_fd);
+       }
+}
diff --git a/ntstatus.c b/ntstatus.c
new file mode 100644 (file)
index 0000000..ca6a17f
--- /dev/null
@@ -0,0 +1,36 @@
+#include <stdio.h>
+
+typedef unsigned uint32;
+typedef unsigned BOOL;
+
+
+#ifdef __GNUC__
+typedef struct {uint32 v;} NTSTATUS;
+#define NT_STATUS(x) ((NTSTATUS) { x })
+#define NT_STATUS_V(x) ((x).v)
+#else
+typedef uint32 NTSTATUS;
+#define NT_STATUS(x) (x)
+#define NT_STATUS_V(x) (x)
+#endif
+
+BOOL bar(NTSTATUS x)
+{
+       return x;
+}
+
+NTSTATUS foo(void)
+{
+       return NT_STATUS(3);
+}
+
+int main()
+{
+       NTSTATUS x;
+       
+       x = foo();
+       bar(1);
+
+       printf("%d\n", NT_STATUS_V(x));
+       return 0;
+}
diff --git a/permute.c b/permute.c
new file mode 100644 (file)
index 0000000..0a1abe9
--- /dev/null
+++ b/permute.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+typedef unsigned long long uint64;
+
+printbits(uint64 x)
+{
+       int i;
+       for (i=0;i<64;i++) {
+               if (x & (((uint64)1)<<i)) {
+                       printf("%d ", i);
+               } 
+       }
+       printf("\n");
+}
+
+void permute(int n)
+{
+       uint64 x=0;
+
+       if (n == 0) return;
+       
+       do {
+               x++;
+               printbits(x);
+       } while (x != ((1<<n)-1));
+}
+
+
+int main(int argc, char *argv[])
+{
+       permute(atoi(argv[1]));
+       return 0;
+}
diff --git a/pes_parse.c b/pes_parse.c
new file mode 100644 (file)
index 0000000..971d947
--- /dev/null
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+typedef unsigned char u8;
+
+#define PAGE_SIZE 0x1000
+
+static void scan_pes(u8 *p, size_t len)
+{
+       u8 *p0 = p;
+       u8 *p1 = p;
+       int nPacketLen, nStreamID, nDTS, nPTS, nHeaderLen;
+
+       while (len > 6) {
+               /* look for a PES start */
+               while (len > 6 && (p[0] || p[1] || p[2] != 1)) { p++; len--; }
+
+               nPacketLen = p[4] << 8 | p[5];
+               nStreamID  = p[3];
+
+               if (p[7] & 0x80) { /* PTS avail */
+                       nPTS  = (p[ 9] & 0x0E) << 29 ;
+                       nPTS |=  p[10]         << 22 ;
+                       nPTS |= (p[11] & 0xFE) << 14 ;
+                       nPTS |=  p[12]         <<  7 ;
+                       nPTS |= (p[13] & 0xFE) >>  1 ;
+               } else {
+                       nPTS = 0;
+               }
+    
+               if (p[7] & 0x40) { /* DTS avail */
+                       nDTS  = (p[14] & 0x0E) << 29 ;
+                       nDTS |=  p[15]         << 22 ;
+                       nDTS |= (p[16] & 0xFE) << 14 ;
+                       nDTS |=  p[17]         <<  7 ;
+                       nDTS |= (p[18] & 0xFE) >>  1 ;
+               } else {
+                       nDTS = 0;
+               }
+
+
+               nHeaderLen = p[8];
+
+               printf("offset=0x%x xsize=0x%x stream_id=0x%x len=0x%x headerlen=%d pts=0x%x dts=0x%x\n", 
+                      (int)(p-p0), (int)(p-p1), nStreamID, nPacketLen, nHeaderLen, nPTS, nDTS);
+
+               p1 = p;
+
+               p    += nHeaderLen + 9;
+               nPacketLen -= nHeaderLen + 3;
+       }
+
+}
+
+int main(int argc, char *argv[])
+{
+       u8 *p;
+       int fd;
+       struct stat st;
+
+       fd = open(argv[1], O_RDONLY);
+       
+       fstat(fd, &st);
+
+       p = mmap(NULL, (st.st_size+(PAGE_SIZE-1))&~(PAGE_SIZE-1), PROT_READ, MAP_PRIVATE|MAP_FILE, fd, 0);
+       
+       scan_pes(p, st.st_size);
+       return 0;
+}
diff --git a/rand_syscall.c b/rand_syscall.c
new file mode 100644 (file)
index 0000000..2abde4c
--- /dev/null
@@ -0,0 +1,50 @@
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <syscall.h>
+
+
+static void rand_syscalls(void)
+{
+       int a[7];
+       int i;
+
+       signal(SIGTERM, exit);
+
+       srandom(getpid() ^ time(NULL));
+
+       while (1) {
+               for (i=0;i<7;i++) a[i] = random();
+               syscall(a[0] % 1000, a[1], a[2], a[3], a[4], a[5], a[6]);
+       }
+}
+
+static void launch(void)
+{
+       waitpid(-1, NULL, WNOHANG);
+       if (fork() == 0) rand_syscalls();
+}
+
+int main(int argc, char *argv[])
+{
+       int nproc=1;
+       int i, status;
+
+       if (argc > 1) {
+               nproc = atoi(argv[1]);
+       }
+
+       signal(SIGTERM, SIG_IGN);
+       signal(SIGCHLD, launch);
+
+       for (i=0;i<nproc;i++) {
+               launch();
+       }
+
+       while (1) {
+               kill(SIGTERM, -getpgrp());
+               sleep(1);
+       }
+}
diff --git a/readloop.c b/readloop.c
new file mode 100644 (file)
index 0000000..8e9bdcc
--- /dev/null
@@ -0,0 +1,48 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/time.h>
+
+struct timeval tp1,tp2;
+
+static void start_timer()
+{
+  gettimeofday(&tp1,NULL);
+}
+
+static double end_timer()
+{
+  gettimeofday(&tp2,NULL);
+  return((tp2.tv_sec - tp1.tv_sec) + 
+        (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
+}
+
+
+char buf[1024*1024];
+
+int main(int argc, char *argv[])
+{
+       char *fname = argv[1];
+       int fd;
+       int count=0;
+
+       fd = open(fname,O_RDONLY);
+
+       while (1) {
+               int ret;
+
+               if (count == 0) {
+                       start_timer();
+               }
+               
+               ret = read(fd, buf, sizeof(buf));
+
+               lseek(fd, 0, SEEK_SET);
+
+               if (count++ == 10) {
+                       printf("%g MB/sec\n", count*ret/(1.0e6*end_timer()));
+                       count=0;
+               }
+       }
+
+       return 0;
+}
diff --git a/rename_loop.c b/rename_loop.c
new file mode 100644 (file)
index 0000000..2306909
--- /dev/null
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+
+static struct timeval tp1,tp2;
+
+void start_timer()
+{
+       gettimeofday(&tp1,NULL);
+}
+
+double end_timer()
+{
+       gettimeofday(&tp2,NULL);
+       return((tp2.tv_sec - tp1.tv_sec) + 
+              (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
+}
+
+int main(void)
+{
+       const char *name1 = "test1.dat";
+       const char *name2 = "test2.dat";
+       int fd, ops;
+
+       fd = open(name1, O_CREAT|O_RDWR|O_TRUNC, 0644);
+       if (fd == -1) {
+               perror("open");
+               exit(1);
+       }
+       close(fd);
+
+       start_timer();
+
+       ops = 0;
+
+       while (1) {
+               if (rename(name1, name2) != 0 ||
+                   rename(name2, name1) != 0) {
+                       perror("rename");
+                       exit(1);
+               }
+               ops++;
+               if (end_timer() >= 1.0) {
+                       printf("%.1f ops/sec\n", (2*ops) / end_timer());
+                       ops = 0;
+                       start_timer();
+               }
+       }
+       
+       return 0;
+}
index 5d78324..c9aa198 100644 (file)
@@ -9,6 +9,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <pty.h>
+#include <fcntl.h>
 #include <utmp.h>
 #include <errno.h>
 #include <readline/readline.h>
@@ -185,6 +186,31 @@ void line_handler(char *line)
 }
 
 
+/* mirror echo mode from a slave terminal to our terminal */
+static void mirror_echo_mode(int fd)
+{  
+       struct termios pterm1, pterm2;
+       
+       if (tcgetattr(fd, &pterm1) != 0) return;
+       if (tcgetattr(0, &pterm2) != 0) return;
+
+       pterm2.c_lflag &= ~ICANON;
+       pterm2.c_lflag &= ~ECHO;
+       pterm2.c_lflag |= ISIG;
+       pterm2.c_cc[VMIN] = 1;
+       pterm2.c_cc[VTIME]=0;
+       pterm2.c_lflag &= ~(ICANON|ISIG|ECHO|ECHONL|ECHOCTL| 
+                           ECHOE|ECHOK|ECHOKE| 
+                           ECHOPRT);
+       if (pterm1.c_lflag) {
+               pterm2.c_lflag |= ECHO;
+       } else {
+               pterm2.c_lflag &= ~ECHO;
+       }
+       tcsetattr(0, TCSANOW, &pterm2);
+}
+
+
 /* setup the slave side of a pty appropriately */
 static void setup_terminal(int fd)
 {
@@ -211,6 +237,8 @@ int main(int argc, char *argv[])
        char *prompt;
        pid_t pid;
        struct termios term, *pterm=NULL;
+       int slave_fd;
+       char slave_name[100];
 
        if (argc < 2 || argv[1][0] == '-') {
                usage();
@@ -226,7 +254,7 @@ int main(int argc, char *argv[])
 
        /* by using forkpty we give a true pty to the child, which means it should 
           behave the same as if run from a terminal */
-       pid = forkpty(&child_fd, NULL, pterm, NULL);
+       pid = forkpty(&child_fd, slave_name, pterm, NULL);
 
        if (pid == (pid_t)-1) {
                perror("forkpty");
@@ -242,6 +270,8 @@ int main(int argc, char *argv[])
                exit(1);
        }
 
+       slave_fd = open(slave_name, O_RDWR);
+
        /* initial blank prompt */
        prompt = strdup("");
 
@@ -295,6 +325,9 @@ int main(int argc, char *argv[])
 
                        rl_set_prompt(prompt);
                        rl_on_new_line_with_prompt();
+                       if (slave_fd != -1) {
+                               mirror_echo_mode(slave_fd);
+                       }
                }
        }
 
index ca8101b..5f791df 100644 (file)
@@ -1,5 +1,4 @@
 #include "rproxy.h"
-#include "librsync/rsync.h"
 
 struct mem_buf {
        char *buf;
@@ -16,8 +15,20 @@ struct file_buf {
 };
 
 
+enum rs_result {RS_DONE};
+
 size_t sig_inbytes, sig_outbytes, sig_zinbytes, sig_zoutbytes;
 
+typedef struct {
+       char *next_in;          /**< Next input byte */
+       size_t avail_in;            /**< Number of bytes available at next_in */
+       int eof_in;                 /**< True if there is no more data
+                                    * after this.  */
+       
+       char *next_out;         /**< Next output byte should be put there */
+       size_t avail_out;           /**< Remaining free space at next_out */
+} rs_buffers_t;
+
 static ssize_t sig_writebuf(void *private, char *buf, size_t len)
 {
        struct mem_buf *bofs = (struct mem_buf *)private;
diff --git a/rtime2.c b/rtime2.c
new file mode 100644 (file)
index 0000000..46d5058
--- /dev/null
+++ b/rtime2.c
@@ -0,0 +1,80 @@
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+/* open a socket to a tcp remote host with the specified port */
+static int open_socket_out(const char *host, int port)
+{
+       struct sockaddr_in sock_out;
+       int res;
+       struct hostent *hp;  
+       struct in_addr addr;
+
+       res = socket(PF_INET, SOCK_STREAM, 0);
+       if (res == -1) {
+               return -1;
+       }
+
+       inet_aton(host, &addr);
+
+       sock_out.sin_addr = addr;
+       sock_out.sin_port = htons(port);
+       sock_out.sin_family = PF_INET;
+
+       if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)) != 0) {
+               close(res);
+               fprintf(stderr,"failed to connect to %s (%s)\n", 
+                       host, strerror(errno));
+               return -1;
+       }
+
+       return res;
+}
+
+
+static void unix_time(time_t t)
+{
+       struct tm *tm;
+
+       tm = gmtime(&t);
+       
+       printf("%04d%02d%02d%02d%02d%02d\n",
+              tm->tm_year + 1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, 
+              tm->tm_min, tm->tm_sec);
+}
+
+int main(int argc, char *argv[])
+{
+       int sock;
+       unsigned t, ofs;
+       char *host;
+
+       if (argc != 3) {
+               printf("rtime <server> <offset>\n");
+               exit(1);
+       }
+
+       host = argv[1];
+       ofs = atoi(argv[2]);
+
+       sock = open_socket_out(argv[1], 37);
+
+       if (read(sock, &t, sizeof(t)) == 4) {
+               unix_time(ofs + ntohl(t) - 2208988800U);
+               return 0;
+       }
+       return -1;
+}
diff --git a/sendfile.c b/sendfile.c
new file mode 100644 (file)
index 0000000..9d52b39
--- /dev/null
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/sendfile.h>
+
+
+ int copy_file(const char *src, const char *dest)
+ {
+       int fd1, fd2;
+       int n;
+        struct stat sb;
+        off_t t;
+       fd1 = open(src, O_RDONLY);
+       if (fd1 == -1) return -1;
+
+       unlink(dest);
+       fd2 = open(dest, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0666);
+       if (fd2 == -1) {
+               close(fd1);
+               return -1;
+       }
+        fstat(fd1, &sb);
+        t = 0;
+        n = sendfile(fd2, fd1, &t, sb.st_size);
+        if (n != sb.st_size) {
+            close(fd2);
+            close(fd1);
+            unlink(dest);
+            return -1;
+        }
+       close(fd1);
+
+       /* the close can fail on NFS if out of space */
+       if (close(fd2) == -1) {
+               unlink(dest);
+               return -1;
+       }
+
+       return 0;
+}
+
+int main(int argc, char *argv[])
+{
+  return copy_file(argv[1], argv[2]);
+}
diff --git a/serialbug.c b/serialbug.c
new file mode 100644 (file)
index 0000000..ba8972d
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <termios.h>
+
+
+void main(int argc,char *argv[])
+{
+char *devname0 = argv[1];
+char *devname1 = argv[2];
+fd_set fds;
+int fd0,fd1;
+int select_return;
+int read_return;
+char buf[10];
+
+fd0 = open(devname0,O_RDWR | O_NONBLOCK);
+fd1 = open(devname1,O_RDWR | O_NONBLOCK);
+
+FD_ZERO(&fds);
+FD_SET(fd0,&fds);
+FD_SET(fd1,&fds);
+
+select_return = select(255,&fds,NULL,NULL,NULL);
+
+printf("select() gave %d\n",select_return);
+
+if (FD_ISSET(fd0,&fds)) 
+  printf("read() of fd0 gave %d\n",read(fd0,buf,10));
+
+if (FD_ISSET(fd1,&fds)) 
+  printf("read() of fd1 gave %d\n",read(fd1,buf,10));
+
+close(fd0);
+close(fd1);
+}
+  
+    
diff --git a/sleeptst.c b/sleeptst.c
new file mode 100644 (file)
index 0000000..3d1983d
--- /dev/null
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <sys/time.h>
+
+
+main()
+{
+struct timeval tp1;
+struct timeval tp2;
+int i;
+
+for (i=0;i<10;i++)
+  {
+
+    gettimeofday(&tp1,NULL);
+    usleep(1*i);
+    gettimeofday(&tp2,NULL);
+
+    printf("diff=%d\n",
+          (tp2.tv_sec-tp1.tv_sec)*1000000 + (tp2.tv_usec-tp1.tv_usec));
+  }
+}
diff --git a/snc.c b/snc.c
new file mode 100644 (file)
index 0000000..fe1001a
--- /dev/null
+++ b/snc.c
@@ -0,0 +1,46 @@
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+
+double walltime(void)
+{
+       struct timeval tv;
+       gettimeofday(&tv, NULL);
+       return tv.tv_sec + 1.0e-6*tv.tv_usec;
+}
+
+main(int argc, char *argv[])
+{
+       int fd;
+       int i;
+       char *buf;
+       int bufsize, sync, loops;
+       double t;
+
+       if (argc < 3) {
+               printf("usage: %s <bufsize> <sync> <loops>\n", argv[0]);
+               exit(1);
+       }
+
+       bufsize = atoi(argv[1]);
+       sync = atoi(argv[2]);
+       loops = atoi(argv[3]);
+
+       buf = (char *)malloc(bufsize);
+       if (!buf) exit(1);
+       memset(buf, 1, bufsize);
+
+       fd = open("sync.dat", O_CREAT|O_TRUNC|O_WRONLY | (sync?O_SYNC:0),0600);
+       t = walltime();
+
+       for (i=0;i<loops;i++) {
+               write(fd, buf, bufsize);
+       }
+
+       t = walltime() - t;
+
+       printf("%g MB/sec\n", (1.0e-6*i*bufsize)/t);
+
+       unlink("sync.dat");
+}
diff --git a/sock_exec.c b/sock_exec.c
new file mode 100644 (file)
index 0000000..be1573b
--- /dev/null
@@ -0,0 +1,146 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#define BOOL int
+
+/****************************************************************************
+Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
+else
+if SYSV use O_NDELAY
+if BSD use FNDELAY
+****************************************************************************/
+int set_blocking(int fd, BOOL set)
+{
+  int val;
+#ifdef O_NONBLOCK
+#define FLAG_TO_SET O_NONBLOCK
+#else
+#ifdef SYSV
+#define FLAG_TO_SET O_NDELAY
+#else /* BSD */
+#define FLAG_TO_SET FNDELAY
+#endif
+#endif
+
+  if((val = fcntl(fd, F_GETFL, 0)) == -1)
+       return -1;
+  if(set) /* Turn blocking on - ie. clear nonblock flag */
+       val &= ~FLAG_TO_SET;
+  else
+    val |= FLAG_TO_SET;
+  return fcntl( fd, F_SETFL, val);
+#undef FLAG_TO_SET
+}
+
+/*******************************************************************
+this is like socketpair but uses tcp. It is used by the Samba
+regression test code
+The function guarantees that nobody else can attach to the socket,
+or if they do that this function fails and the socket gets closed
+returns 0 on success, -1 on failure
+the resulting file descriptors are symmetrical
+ ******************************************************************/
+static int socketpair_tcp(int fd[2])
+{
+       int listener;
+       struct sockaddr sock;
+       struct sockaddr_in sock2;
+       socklen_t socklen = sizeof(sock);
+       int connect_done = 0;
+       
+       fd[0] = fd[1] = listener = -1;
+
+       memset(&sock, 0, sizeof(sock));
+       
+       if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
+
+        memset(&sock2, 0, sizeof(sock2));
+#ifdef HAVE_SOCK_SIN_LEN
+        sock2.sin_len = sizeof(sock2);
+#endif
+        sock2.sin_family = PF_INET;
+
+        bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
+
+       if (listen(listener, 1) != 0) goto failed;
+
+       if (getsockname(listener, &sock, &socklen) != 0) goto failed;
+
+       if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
+
+       set_blocking(fd[1], 0);
+
+       if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
+               if (errno != EINPROGRESS) goto failed;
+       } else {
+               connect_done = 1;
+       }
+
+       if ((fd[0] = accept(listener, &sock, &socklen)) == -1) goto failed;
+
+       close(listener);
+       if (connect_done == 0) {
+               if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
+                   && errno != EISCONN) goto failed;
+       }
+
+       set_blocking(fd[1], 1);
+
+       /* all OK! */
+       return 0;
+
+ failed:
+       if (fd[0] != -1) close(fd[0]);
+       if (fd[1] != -1) close(fd[1]);
+       if (listener != -1) close(listener);
+       return -1;
+}
+
+
+/*******************************************************************
+run a program on a local tcp socket, this is used to launch smbd
+when regression testing
+the return value is a socket which is attached to a subprocess
+running "prog". stdin and stdout are attached. stderr is left
+attached to the original stderr
+ ******************************************************************/
+int sock_exec(const char *prog)
+{
+       int fd[2];
+       if (socketpair_tcp(fd) != 0) return -1;
+       if (fork() == 0) {
+               close(fd[0]);
+               close(0);
+               close(1);
+               dup(fd[1]);
+               dup(fd[1]);
+               exit(system(prog));
+       }
+       close(fd[1]);
+       return fd[0];
+}
+
+
+int main(int argc, char *argv[])
+{
+       int fd;
+       char buf[100];
+       int n;
+
+       fd = sock_exec(argv[1]);
+
+       while ((n = read(fd, buf, sizeof(buf))) > 0) {
+               write(1, buf, n);
+       }
+       return 0;
+}
diff --git a/sockspy-rpc.c b/sockspy-rpc.c
new file mode 100644 (file)
index 0000000..f333845
--- /dev/null
@@ -0,0 +1,243 @@
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
+#define NTLMSSP_NEGOTIATE_UNICODE          0x00000001
+#define NTLMSSP_NEGOTIATE_OEM              0x00000002
+#define NTLMSSP_REQUEST_TARGET             0x00000004
+#define NTLMSSP_NEGOTIATE_SIGN             0x00000010 /* Message integrity */
+#define NTLMSSP_NEGOTIATE_SEAL             0x00000020 /* Message confidentiality */
+#define NTLMSSP_NEGOTIATE_DATAGRAM_STYLE   0x00000040
+#define NTLMSSP_NEGOTIATE_LM_KEY           0x00000080
+#define NTLMSSP_NEGOTIATE_NETWARE          0x00000100
+#define NTLMSSP_NEGOTIATE_NTLM             0x00000200
+#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED  0x00001000
+#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000
+#define NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL  0x00004000
+#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN      0x00008000
+#define NTLMSSP_NEGOTIATE_128              0x20000000 /* 128-bit encryption */
+#define NTLMSSP_NEGOTIATE_KEY_EXCH         0x40000000
+#define NTLMSSP_NEGOTIATE_NTLM2            0x00080000
+
+static void replace_str(char *buf, int n)
+{
+       char *p;
+       p = memmem(buf, n, "NTLMSSP", 7);
+       if (p && p[8] == 1) {
+               unsigned x;
+
+               x = *(unsigned *)(p+12);
+               printf("flags were 0x%08x\n", x);
+
+               x = 0x00000011;
+
+               printf("replacing challenge flags with 0x%08x\n", x);
+               *(unsigned *)(p+12) = x;
+       }
+}
+
+/* open a socket to a tcp remote host with the specified port */
+static int open_socket_out(const char *host, int port)
+{
+       struct sockaddr_in sock_out;
+       int res;
+       struct hostent *hp;  
+       struct in_addr addr;
+
+       res = socket(PF_INET, SOCK_STREAM, 0);
+       if (res == -1) {
+               return -1;
+       }
+
+       if (inet_pton(AF_INET, host, &addr) > 0) {
+               memcpy(&sock_out.sin_addr, &addr, sizeof(addr));
+       } else {
+               hp = gethostbyname(host);
+               if (!hp) {
+                       fprintf(stderr,"unknown host %s\n", host);
+                       return -1;
+               }
+               memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length);
+       }
+
+       sock_out.sin_port = htons(port);
+       sock_out.sin_family = PF_INET;
+
+       if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)) != 0) {
+               close(res);
+               fprintf(stderr,"failed to connect to %s (%s)\n", 
+                       host, strerror(errno));
+               return -1;
+       }
+
+       return res;
+}
+
+
+/*
+  open a socket of the specified type, port and address for incoming data
+*/
+int open_socket_in(int port)
+{
+       struct sockaddr_in sock;
+       int res;
+       int one=1;
+
+       memset(&sock,0,sizeof(sock));
+
+#ifdef HAVE_SOCK_SIN_LEN
+       sock.sin_len = sizeof(sock);
+#endif
+       sock.sin_port = htons(port);
+       sock.sin_family = AF_INET;
+
+       res = socket(AF_INET, SOCK_STREAM, 0);
+       if (res == -1) { 
+               fprintf(stderr, "socket failed\n"); return -1; 
+               return -1;
+       }
+
+       setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
+
+       if (bind(res, (struct sockaddr *)&sock, sizeof(sock)) < 0) { 
+               return(-1); 
+       }
+
+       return res;
+}
+
+/* write to a file descriptor, making sure we get all the data out or
+ * die trying */
+static void write_all(int fd, unsigned char *s, size_t n)
+{
+       while (n) {
+               int r;
+               r = write(fd, s, n);
+               if (r <= 0) {
+                       exit(1);
+               }
+               s += r;
+               n -= r;
+       }
+}
+
+static void main_loop(int sock1, int sock2)
+{
+       unsigned char buf[1024];
+       int log1, log2, i=0;
+
+       do {
+               char *fname1, *fname2;
+               asprintf(&fname1, "sockspy-in.%d", i);
+               asprintf(&fname2, "sockspy-out.%d", i);
+               log1 = open(fname1, O_WRONLY|O_CREAT|O_EXCL, 0644);
+               log2 = open(fname2, O_WRONLY|O_CREAT|O_EXCL, 0644);
+               free(fname1);
+               free(fname2);
+               i++;
+       } while (i<1000 && (log1 == -1 || log2 == -1));
+
+       if (log1 == -1 || log2 == -1) {
+               fprintf(stderr,"Failed to open log files\n");
+               return;
+       }
+
+       while (1) {
+               fd_set fds;
+               int ret;
+
+               FD_ZERO(&fds);
+               FD_SET(sock1, &fds);
+               FD_SET(sock2, &fds);
+
+               ret = select(MAX(sock1, sock2)+1, &fds, NULL, NULL, NULL);
+               if (ret == -1 && errno == EINTR) continue;
+               if (ret <= 0) break;
+
+               if (FD_ISSET(sock1, &fds)) {
+                       int n = read(sock1, buf, sizeof(buf));
+                       if (n <= 0) break;
+
+                       replace_str(buf, n);
+
+                       write_all(sock2, buf, n);
+                       write_all(log1, buf, n);
+               }
+
+               if (FD_ISSET(sock2, &fds)) {
+                       int n = read(sock2, buf, sizeof(buf));
+                       if (n <= 0) break;
+
+                       replace_str(buf, n);
+
+                       write_all(sock1, buf, n);
+                       write_all(log2, buf, n);
+               }
+       }       
+}
+
+int main(int argc, char *argv[])
+{
+       int listen_port, dest_port;
+       char *host;
+       int sock_in;
+       int sock_out;
+       int listen_fd;
+       struct sockaddr addr;
+       int in_addrlen = sizeof(addr);
+
+       if (argc < 4) {
+               printf("Usage: sockspy <inport> <host> <port>\n");
+               exit(1);
+       }
+
+       listen_port = atoi(argv[1]);
+       host = argv[2];
+       dest_port = atoi(argv[3]);
+
+       listen_fd = open_socket_in(listen_port);
+
+       if (listen_fd == -1) {
+               fprintf(stderr,"listen on port %d failed - %s\n", 
+                       listen_port, strerror(errno));
+               exit(1);
+       }
+
+       if (listen(listen_fd, 5) == -1) {
+               fprintf(stderr,"listen failed\n");
+               exit(1);
+       }
+
+       sock_in = accept(listen_fd,&addr,&in_addrlen);
+
+       if (sock_in == -1) {
+               fprintf(stderr,"accept on port %d failed - %s\n", 
+                       listen_port, strerror(errno));
+               exit(1);
+       }
+
+       close(listen_fd);
+
+       sock_out = open_socket_out(host, dest_port);
+       if (sock_out == -1) {
+               exit(1);
+       }
+
+       main_loop(sock_in, sock_out);
+       return 0;
+}
diff --git a/stack.c b/stack.c
new file mode 100644 (file)
index 0000000..c65cd48
--- /dev/null
+++ b/stack.c
@@ -0,0 +1,14 @@
+
+void r(int depth)
+{
+       int x = depth;
+       printf("depth=%d &x=%p\n", depth, &x);
+
+       if (depth == 0) return;
+       r(depth-1);
+}
+
+main()
+{
+       r(100);
+}
diff --git a/stringize.c b/stringize.c
new file mode 100644 (file)
index 0000000..fdeab71
--- /dev/null
@@ -0,0 +1,12 @@
+#define xx(y) char *y; printf("y");
+
+#define stringize(x) #x
+
+#define FOO 3
+
+#define MYASSERT(x) do { if (x) { printf("Assert failed '%s'\n", #x); }} while (0)
+
+main()
+{
+       MYASSERT(x > y);
+}
diff --git a/sysconf.c b/sysconf.c
new file mode 100644 (file)
index 0000000..d55aec0
--- /dev/null
+++ b/sysconf.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#include <unistd.h>
+
+main()
+{
+       int limit = __sysconf (_SC_NGROUPS_MAX);
+       printf("Limit=%d\n", limit);
+}
diff --git a/time_speed.c b/time_speed.c
new file mode 100644 (file)
index 0000000..0f79658
--- /dev/null
@@ -0,0 +1,34 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(void)
+{
+       int i;
+       time_t t, t2;
+       struct timeval tv, tv2;
+
+       t = time(NULL);
+
+       i=0;
+
+       while (1) {
+               t2 = time(NULL);
+               i++;
+               if (t2 - t > 10) break;
+       }
+       
+       printf("time(): %g ops/sec\n", (1.0*i) / (t2-t));
+
+
+       gettimeofday(&tv, NULL);
+       i=0;
+
+       while (1) {
+               gettimeofday(&tv2, NULL);
+               i++;
+               if (tv2.tv_sec - tv.tv_sec > 10) break;
+       }
+       
+       printf("gettimeofday(): %g ops/sec\n", (1.0*i) / (tv2.tv_sec - tv.tv_sec));
+       return 0;
+}
diff --git a/timing_attack.c b/timing_attack.c
new file mode 100644 (file)
index 0000000..0fa56b8
--- /dev/null
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <sys/time.h>
+#include <time.h>
+#include <string.h>
+
+
+static struct timeval tp1,tp2;
+
+static void start_timer()
+{
+       gettimeofday(&tp1,NULL);
+}
+
+static double end_timer()
+{
+       gettimeofday(&tp2,NULL);
+       return (tp2.tv_sec + (tp2.tv_usec*1.0e-6)) - 
+               (tp1.tv_sec + (tp1.tv_usec*1.0e-6));
+}
+
+static void attack_it(const char *target, int len)
+{
+       int i;
+       double totals[256];
+       double this_run[256];
+       char teststr[len+1];
+       int c, r, runs, min_c;
+       double min;
+
+       runs = 1000000;
+
+
+       for (i=0;i<len;i++) {
+               memset(totals, 0, sizeof(totals));
+
+               for (r=0;r<runs;r++) {
+                       for (c=0;c<256;c++) {
+                               start_timer();
+                               teststr[i] = c;
+                               memcmp(teststr, target, i+1);
+                               this_run[c] = end_timer();
+                       }
+                       for (c=0;c<256;c++) {
+//                             printf("%3d %lf\n", c, 1000*1000*this_run[c]);
+                               totals[c] += this_run[c];
+                       }
+               }
+
+               min_c = 0;
+               min = totals[0];
+               for (c=1;c<256;c++) {
+                       if (totals[c] < min) {
+                               min = totals[c];
+                               min_c = c;
+                       }
+               }
+               printf("min_c=%d\n", min_c);
+       }
+}
+
+int main(int argc, char *argv[])
+{
+       attack_it(argv[1], strlen(argv[1]));
+       return 0;
+}
diff --git a/tprog.c b/tprog.c
new file mode 100644 (file)
index 0000000..518b834
--- /dev/null
+++ b/tprog.c
@@ -0,0 +1,74 @@
+#include <time.h>
+#include <stdio.h>
+
+#define TM_YEAR_BASE 1900
+
+/*******************************************************************
+yield the difference between *A and *B, in seconds, ignoring leap seconds
+********************************************************************/
+static int tm_diff(struct tm *a, struct tm *b)
+{
+       int ay = a->tm_year + (TM_YEAR_BASE - 1);
+       int by = b->tm_year + (TM_YEAR_BASE - 1);
+       int intervening_leap_days =
+               (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
+       int years = ay - by;
+       int days = 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
+       int hours = 24*days + (a->tm_hour - b->tm_hour);
+       int minutes = 60*hours + (a->tm_min - b->tm_min);
+       int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
+
+       return seconds;
+}
+
+/*******************************************************************
+  return the UTC offset in seconds west of UTC, or 0 if it cannot be determined
+  ******************************************************************/
+static int TimeZone(time_t t)
+{
+       struct tm *tm = gmtime(&t);
+       struct tm tm_utc;
+       if (!tm)
+               return 0;
+       tm_utc = *tm;
+       tm = localtime(&t);
+       if (!tm)
+               return 0;
+       return tm_diff(&tm_utc,tm);
+}
+
+time_t timegm2(struct tm *tm) 
+{
+       struct tm tm2, tm3;
+       time_t t;
+
+       tm2 = *tm;
+
+       t = mktime(&tm2);
+       tm3 = *localtime(&t);
+       tm2 = *tm;
+       tm2.tm_isdst = tm3.tm_isdst;
+       t = mktime(&tm2);
+       t -= TimeZone(t);
+
+       return t;
+}
+
+main()
+{
+       struct tm tm;
+       time_t tnow, t;
+
+       tnow = time(NULL);
+
+       for (t=tnow; t < tnow + (400 * 24 * 60 * 60); t += 600) {
+               tm = *localtime(&t);
+
+               if (timegm2(&tm) != timegm(&tm)) {
+                       printf("diff=%d at %s", 
+                              timegm2(&tm) - timegm(&tm), 
+                              asctime(&tm));
+               }
+       }
+       return 0;
+}
diff --git a/tstid.c b/tstid.c
new file mode 100644 (file)
index 0000000..19a9d14
--- /dev/null
+++ b/tstid.c
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+
+void report()
+{
+printf("uid=%d euid=%d\n",getuid(),geteuid());
+}
+
+main()
+{
+report();
+seteuid(65534);
+report();
+seteuid(-2);
+report();
+}
diff --git a/udpspy.c b/udpspy.c
new file mode 100644 (file)
index 0000000..42120df
--- /dev/null
+++ b/udpspy.c
@@ -0,0 +1,200 @@
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
+/* open a socket to a remote host with the specified port */
+static int open_socket_out(const char *host, int port)
+{
+       struct sockaddr_in sock_out;
+       int res;
+       struct hostent *hp;  
+       struct in_addr addr;
+
+       res = socket(PF_INET, SOCK_DGRAM, 0);
+       if (res == -1) {
+               return -1;
+       }
+
+       if (inet_pton(AF_INET, host, &addr) > 0) {
+               memcpy(&sock_out.sin_addr, &addr, sizeof(addr));
+       } else {
+               hp = gethostbyname(host);
+               if (!hp) {
+                       fprintf(stderr,"unknown host %s\n", host);
+                       return -1;
+               }
+               memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length);
+       }
+
+       sock_out.sin_port = htons(port);
+       sock_out.sin_family = PF_INET;
+
+       if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)) != 0) {
+               close(res);
+               fprintf(stderr,"failed to connect to %s (%s)\n", 
+                       host, strerror(errno));
+               return -1;
+       }
+
+       return res;
+}
+
+
+/*
+  open a socket of the specified type, port and address for incoming data
+*/
+int open_socket_in(int port)
+{
+       struct sockaddr_in sock;
+       int res;
+       int one=1;
+
+       memset(&sock,0,sizeof(sock));
+
+#ifdef HAVE_SOCK_SIN_LEN
+       sock.sin_len = sizeof(sock);
+#endif
+       sock.sin_port = htons(port);
+       sock.sin_family = AF_INET;
+
+       res = socket(AF_INET, SOCK_DGRAM, 0);
+       if (res == -1) { 
+               fprintf(stderr, "socket failed\n"); return -1; 
+               return -1;
+       }
+
+       setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
+
+       if (bind(res, (struct sockaddr *)&sock, sizeof(sock)) < 0) { 
+               return(-1); 
+       }
+
+       return res;
+}
+
+/* write to a file descriptor, making sure we get all the data out or
+ * die trying */
+static void write_all(int fd, unsigned char *s, size_t n)
+{
+       usleep(1000);
+       while (n) {
+               int r;
+               r = write(fd, s, n);
+               if (r <= 0) {
+                       exit(1);
+               }
+               s += r;
+               n -= r;
+       }
+}
+
+static void main_loop(int sock1, int sock2)
+{
+       unsigned char buf[1024];
+       int log1, log2, i=0;
+       struct sockaddr from;
+       socklen_t fromlen = sizeof(from);
+       int connected = 0;
+
+       do {
+               char *fname1, *fname2;
+               asprintf(&fname1, "udpspy-in.%d", i);
+               asprintf(&fname2, "udpspy-out.%d", i);
+               log1 = open(fname1, O_WRONLY|O_CREAT|O_EXCL, 0644);
+               log2 = open(fname2, O_WRONLY|O_CREAT|O_EXCL, 0644);
+               free(fname1);
+               free(fname2);
+               i++;
+       } while (i<1000 && (log1 == -1 || log2 == -1));
+
+       if (log1 == -1 || log2 == -1) {
+               fprintf(stderr,"Failed to open log files\n");
+               return;
+       }
+
+       while (1) {
+               fd_set fds;
+               int ret;
+
+               FD_ZERO(&fds);
+               FD_SET(sock1, &fds);
+               FD_SET(sock2, &fds);
+
+               ret = select(MAX(sock1, sock2)+1, &fds, NULL, NULL, NULL);
+               if (ret == -1 && errno == EINTR) continue;
+               if (ret <= 0) break;
+
+               if (FD_ISSET(sock1, &fds)) {
+                       int n = recvfrom(sock1, buf, sizeof(buf), 0, &from, &fromlen);
+                       if (n <= 0) break;
+
+                       if (!connected) {
+                               connect(sock1,&from,sizeof(from));
+                               connected = 1;
+                       }
+
+                       printf("out %d bytes\n", n);
+                       write_all(sock2, buf, n);
+                       write_all(log1, buf, n);
+               }
+
+               if (FD_ISSET(sock2, &fds)) {
+                       int n = read(sock2, buf, sizeof(buf));
+                       if (n <= 0) break;
+
+                       printf("in %d bytes\n", n);
+                       write_all(sock1, buf, n);
+                       write_all(log2, buf, n);
+               }
+       }       
+}
+
+int main(int argc, char *argv[])
+{
+       int listen_port, dest_port;
+       char *host;
+       int sock_in;
+       int sock_out;
+       struct sockaddr addr;
+       int in_addrlen = sizeof(addr);
+
+       if (argc < 4) {
+               printf("Usage: sockspy <inport> <host> <port>\n");
+               exit(1);
+       }
+
+       listen_port = atoi(argv[1]);
+       host = argv[2];
+       dest_port = atoi(argv[3]);
+
+       sock_in = open_socket_in(listen_port);
+
+       if (sock_in == -1) {
+               fprintf(stderr,"sock on port %d failed - %s\n", 
+                       listen_port, strerror(errno));
+               exit(1);
+       }
+
+       sock_out = open_socket_out(host, dest_port);
+       if (sock_out == -1) {
+               exit(1);
+       }
+
+       main_loop(sock_in, sock_out);
+       return 0;
+}
diff --git a/usleep.c b/usleep.c
new file mode 100644 (file)
index 0000000..5cecff3
--- /dev/null
+++ b/usleep.c
@@ -0,0 +1,31 @@
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+
+static struct timeval tp1,tp2;
+
+static void start_timer()
+{
+       gettimeofday(&tp1,NULL);
+}
+
+static double end_timer()
+{
+       gettimeofday(&tp2,NULL);
+       return (tp2.tv_sec + (tp2.tv_usec*1.0e-6)) - 
+               (tp1.tv_sec + (tp1.tv_usec*1.0e-6));
+}
+
+int main(int argc, char *argv[])
+{
+       unsigned long t;
+
+       t = atoi(argv[1]);
+
+       while (1) {
+               start_timer();
+               usleep(t);
+               printf("%f milliseconds\n", end_timer() * 1000);
+       }
+       return 0;
+}
diff --git a/werror.c b/werror.c
new file mode 100644 (file)
index 0000000..7919822
--- /dev/null
+++ b/werror.c
@@ -0,0 +1,10 @@
+
+typedef struct { unsigned x; } FOOBAR;
+
+void bar(unsigned, FOOBAR, unsigned);
+
+main()
+{
+       FOOBAR foo = (FOOBAR){3};
+       bar(1, foo, 2);
+}
diff --git a/xkeys.c b/xkeys.c
new file mode 100644 (file)
index 0000000..dc492d6
--- /dev/null
+++ b/xkeys.c
@@ -0,0 +1,187 @@
+#ifdef XWINDOWS
+
+#ifdef __TURBOC__
+#include "tcinc.h"
+#else
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <X11/Xos.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#endif
+
+#define EXTERN extern
+#include "bug.h"
+
+
+Display *Dpy=NULL;
+Window ww=0;
+
+
+/*******************************************************************
+send one keysym to a window
+********************************************************************/
+int send_key(Display *dpy,Window w,int state,int keysym)
+{
+  static XKeyEvent event;
+  static count=0;
+  event.serial = count++;
+  event.type = 2;
+  event.send_event = 1;
+  event.x = event.y = 0;
+  event.x_root = event.y_root = 0;
+  event.same_screen = 1;
+  event.time = 0;
+  event.window = w;
+  event.subwindow = w;
+  event.root = 0;
+  event.state = state;
+  event.keycode = XKeysymToKeycode(dpy,keysym);
+  XSendEvent(dpy,w, True, KeyPressMask, &event);
+  return 0;
+}
+
+
+/*******************************************************************
+find a window that matches a name
+********************************************************************/
+int find_window(Display *dpy, Window w,char *match)
+{
+  Window root, parent;
+  unsigned int nchildren;
+  Window *children = NULL;
+  int n;
+  char *name = NULL;
+  sstring aname;
+  
+  XFetchName (dpy, w, &name);
+
+  if (!name)
+    {
+      XWindowAttributes wattr;
+      XGetWindowAttributes(dpy,w,&wattr); /* do check return - Linus */
+      sprintf(aname,"%dx%d",wattr.width,wattr.height);
+      name = aname;
+    }
+
+  if (name) Debug(3,"Found window '%s'\n",name);
+  
+  if (name && strncmp(name,match,strlen(match)) == 0)
+    {
+      Debug(1,"matched %s to %s\n",name,match);
+      if (name && name != aname) XFree ((char *) name);
+      if (children) XFree ((char *) children);
+      return(w);
+    }
+
+  if (name && name != aname) XFree ((char *) name);   
+  
+  if (XQueryTree (dpy, w, &root, &parent, &children, &nchildren))
+    for (n = 0; n < nchildren; n++)
+      {
+       Window Ww = find_window (dpy, children[n],match);
+       if (Ww != 0) return(Ww);
+      }
+  if (children) XFree ((char *) children);
+  return 0;
+}
+
+
+
+/*******************************************************************
+open a window for writing keystrokes to
+********************************************************************/
+FN BOOL X_open_window(char *match)
+{
+  Dpy = XOpenDisplay (NULL);
+  if (!Dpy) {
+    Error("unable to open display \"%s\"\n",XDisplayName (NULL));
+    return False;
+  }
+
+  ww = find_window (Dpy, RootWindow(Dpy, DefaultScreen(Dpy)),match);
+
+  if (!ww)
+    {
+      Error("can't find window matching %s\n",match);
+      return False;
+    }
+
+  return True;
+}
+
+
+/*******************************************************************
+close the keystroke window
+********************************************************************/
+FN void X_close_window(void)
+{
+  if (Dpy)
+    XCloseDisplay(Dpy);
+  Dpy = NULL;
+  ww = 0;
+}
+
+
+/*******************************************************************
+send a string to a window
+********************************************************************/
+FN BOOL X_send_string(char *str)
+{
+  char s[1024];
+  static int state = 0;
+  char *tok;
+
+  if (!Dpy || !ww) 
+    return(False);
+
+  strcpy(s,str);
+  
+  tok = strtok(s," \t\n\r");
+  do
+    {
+      int keysym = XStringToKeysym(tok);
+      if (strlen(tok) == 1 && *tok>='A' && *tok <='Z')
+       {
+         state ^= ShiftMask;     
+         send_key(Dpy,ww,state,XK_Shift_L);
+         send_key(Dpy,ww,state,keysym);
+         state ^= ShiftMask;     
+         send_key(Dpy,ww,state,XK_Shift_L);
+       }      
+      else
+       {
+         if (IsModifierKey(keysym))       
+           {
+             Debug(3,"modifier %d\n",keysym);
+             switch (keysym)
+               {
+               case XK_Shift_L:
+               case XK_Shift_R:
+                 state ^= ShiftMask;
+                 break;
+               case XK_Control_L:
+               case XK_Control_R:
+                 state ^= ControlMask;
+                 break;
+               case XK_Alt_L:
+               case XK_Alt_R:
+                 state ^= Mod1Mask;
+                 break;
+               }
+           }
+         send_key(Dpy,ww,state,keysym);
+       }
+    }
+  while ((tok = strtok(NULL," \t\n\r")));
+
+  XFlush(Dpy);
+  return True;
+}
+
+#endif