From 33805b2aa3b705b04c1b9f5f619eda24c2bb8d62 Mon Sep 17 00:00:00 2001
From: Per Hedbor <ph@opera.com>
Date: Sat, 12 Aug 2000 08:18:22 +0200
Subject: [PATCH] New module for roxen specific stuff

Rev: src/modules/_Roxen/.cvsignore:1.1
Rev: src/modules/_Roxen/Makefile.in:1.1
Rev: src/modules/_Roxen/acconfig.h:1.1
Rev: src/modules/_Roxen/configure.in:1.1
Rev: src/modules/_Roxen/roxen.c:1.1
---
 .gitattributes                  |   2 +
 src/modules/_Roxen/.cvsignore   |  15 ++
 src/modules/_Roxen/.gitignore   |  15 ++
 src/modules/_Roxen/Makefile.in  |  11 ++
 src/modules/_Roxen/acconfig.h   |   0
 src/modules/_Roxen/configure.in |   6 +
 src/modules/_Roxen/roxen.c      | 271 ++++++++++++++++++++++++++++++++
 7 files changed, 320 insertions(+)
 create mode 100644 src/modules/_Roxen/.cvsignore
 create mode 100644 src/modules/_Roxen/.gitignore
 create mode 100644 src/modules/_Roxen/Makefile.in
 create mode 100644 src/modules/_Roxen/acconfig.h
 create mode 100644 src/modules/_Roxen/configure.in
 create mode 100644 src/modules/_Roxen/roxen.c

diff --git a/.gitattributes b/.gitattributes
index fb3c607fc0..c7abbe7f33 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -449,6 +449,8 @@ testfont binary
 /src/modules/_Image_XFace/configure.in foreign_ident
 /src/modules/_Image_XFace/image_xface.c foreign_ident
 /src/modules/_Image_XFace/testsuite.in foreign_ident
+/src/modules/_Roxen/Makefile.in foreign_ident
+/src/modules/_Roxen/configure.in foreign_ident
 /src/modules/_math/Makefile.in foreign_ident
 /src/modules/_math/configure.in foreign_ident
 /src/modules/_math/math.c foreign_ident
diff --git a/src/modules/_Roxen/.cvsignore b/src/modules/_Roxen/.cvsignore
new file mode 100644
index 0000000000..d45d29b97f
--- /dev/null
+++ b/src/modules/_Roxen/.cvsignore
@@ -0,0 +1,15 @@
+.pure
+Makefile
+config.h
+config.h.in
+config.log
+config.status
+configure
+dependencies
+linker_options
+make_variables
+modlist_headers
+modlist_segment
+module_testsuite
+stamp-h
+stamp-h.in
diff --git a/src/modules/_Roxen/.gitignore b/src/modules/_Roxen/.gitignore
new file mode 100644
index 0000000000..14854305fb
--- /dev/null
+++ b/src/modules/_Roxen/.gitignore
@@ -0,0 +1,15 @@
+/.pure
+/Makefile
+/config.h
+/config.h.in
+/config.log
+/config.status
+/configure
+/dependencies
+/linker_options
+/make_variables
+/modlist_headers
+/modlist_segment
+/module_testsuite
+/stamp-h
+/stamp-h.in
diff --git a/src/modules/_Roxen/Makefile.in b/src/modules/_Roxen/Makefile.in
new file mode 100644
index 0000000000..e9832b7870
--- /dev/null
+++ b/src/modules/_Roxen/Makefile.in
@@ -0,0 +1,11 @@
+# $Id: Makefile.in,v 1.1 2000/08/12 06:18:22 per Exp $
+@make_variables@
+VPATH=@srcdir@:@srcdir@/../..:../..
+OBJS=roxen.o
+MODULE_LDFLAGS=@LDFLAGS@
+#  streamed_parser.o
+
+CONFIG_HEADERS=@CONFIG_HEADERS@
+
+@dynamic_module_makefile@
+@dependencies@
diff --git a/src/modules/_Roxen/acconfig.h b/src/modules/_Roxen/acconfig.h
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/modules/_Roxen/configure.in b/src/modules/_Roxen/configure.in
new file mode 100644
index 0000000000..2c626de821
--- /dev/null
+++ b/src/modules/_Roxen/configure.in
@@ -0,0 +1,6 @@
+# $Id: configure.in,v 1.1 2000/08/12 06:18:22 per Exp $
+AC_INIT(roxen.c)
+AC_CONFIG_HEADER(config.h)
+AC_MODULE_INIT()
+
+AC_OUTPUT(Makefile,echo FOO >stamp-h )
diff --git a/src/modules/_Roxen/roxen.c b/src/modules/_Roxen/roxen.c
new file mode 100644
index 0000000000..5e6a76db2c
--- /dev/null
+++ b/src/modules/_Roxen/roxen.c
@@ -0,0 +1,271 @@
+#define NO_PIKE_SHORTHAND
+
+#include "global.h"
+#include "config.h"
+
+
+#include "machine.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
+#include <limits.h>
+
+#include "fdlib.h"
+#include "stralloc.h"
+#include "pike_macros.h"
+#include "machine.h"
+#include "object.h"
+#include "constants.h"
+#include "interpret.h"
+#include "svalue.h"
+#include "mapping.h"
+#include "array.h"
+#include "builtin_functions.h"
+#include "module_support.h"
+#include "backend.h"
+#include "threads.h"
+#include "operators.h"
+
+
+/**** CLASS HeaderParser */
+
+#define THP ((struct header_buf *)Pike_fp->current_object->storage)
+struct  header_buf
+{
+  char headers[8192];
+  char *pnt;
+  int left;
+};
+
+static void f_hp_feed( INT32 args )
+{
+  struct pike_string *str = Pike_sp[-1].u.string;
+  int slash_n = 0, cnt, num;
+  char *pp,*ep;
+  struct svalue *tmp;
+  struct mapping *headers;
+  int os=0,i,j,l;
+  unsigned char *in;
+
+  if( Pike_sp[-1].type != PIKE_T_STRING )
+    error("Wrong type of argument to feed()\n");
+
+  if( str->len >= THP->left )
+    error("Too many headers\n");
+
+  MEMCPY( THP->pnt, str->str, str->len );
+
+  for( ep=(THP->pnt+str->len),
+         pp=MAXIMUM(THP->headers,THP->pnt-3); 
+       pp<ep && slash_n<2; 
+       pp++ )
+    if( *pp == '\n' )
+      slash_n++;
+    else if( *pp != '\r' )
+      slash_n=0;
+  
+  THP->left -= str->len;
+  THP->pnt += str->len;
+  THP->pnt[0] = 0;
+  pop_n_elems( args );
+  if( slash_n != 2 )
+  {
+    /* check for HTTP/0.9? */
+    push_int( 0 );
+    return;
+  }
+
+  push_text( pp ); // leftovers
+  headers = allocate_mapping( 5 );
+  in = THP->headers;
+  l = pp - THP->headers;
+  /* find first line here */
+  for( i = 0; i < l; i++ )
+    if( in[i] == '\n' )
+      break;
+
+  if( in[i-1] != '\r' ) 
+    i++;
+
+  push_string( make_shared_binary_string( in, i-1 ) );
+  in += i; l -= i;
+  if( *in == '\n' ) (in++),(l--);
+
+  for(i = 0; i < l; i++)
+  {
+    if( in[i] == ':' )
+    {
+      /* in[os..i-1] == the header */
+      for(j=os;j<i;j++) if(in[j] > 63 && in[j] < 91) in[j]+=32;
+      push_string(make_shared_binary_string((char*)in+os,i-os));
+      os = i+1;
+      while(in[os]==' ') os++;
+      for(j=os;j<l;j++) 
+        if( in[j] == '\n' || in[j]=='\r')
+        { 
+          break; 
+        }
+      push_string(make_shared_binary_string((char*)in+os,j-os));
+
+      if((tmp = low_mapping_lookup(headers, Pike_sp-2)))
+      {
+        f_aggregate( 1 );
+        if( tmp->type == PIKE_T_ARRAY )
+        {
+          tmp->u.array->refs++;
+          push_array(tmp->u.array);
+          map_delete(headers, Pike_sp-3);
+          f_add(2);
+        } else {
+          tmp->u.string->refs++;
+          push_string(tmp->u.string);
+          f_aggregate(1);
+          map_delete(headers, Pike_sp-3);
+          f_add(2);
+        }
+      }
+      mapping_insert(headers, Pike_sp-2, Pike_sp-1);
+      pop_n_elems(2);
+      if( in[j+1] == '\n' ) j++;
+      os = i = j+1;
+    }
+  }
+  push_mapping( headers );
+  f_aggregate( 3 );             /* data, headers */
+}
+
+static void f_hp_create( INT32 args )
+{
+  THP->pnt = THP->headers;
+  THP->left = 8192;
+}
+/**** END CLASS HeaderParser */
+
+static void f_make_http_headers( INT32 args )
+{
+  int total_len = 0, e;
+  char *pnt;
+  struct mapping *m;
+  struct keypair *k;
+  struct pike_string *res;
+  if( Pike_sp[-1].type != PIKE_T_MAPPING )
+    error("Wrong argument type to make_http_headers(mapping heads)\n");
+
+  m = Pike_sp[-1].u.mapping;
+  /* loop to check len */
+  NEW_MAPPING_LOOP( m->data )
+  {
+    if( k->ind.type != PIKE_T_STRING || k->ind.u.string->size_shift )
+      error("Wrong argument type to make_http_headers("
+            "mapping(string(8bit):string(8bit)|array(string(8bit))) heads)\n");
+    if( k->val.type == PIKE_T_STRING )
+      total_len +=  k->val.u.string->len + 2 + k->ind.u.string->len + 2;
+    else if( k->val.type == PIKE_T_ARRAY )
+    {
+      struct array *a = k->val.u.array;
+      int i, kl = k->ind.u.string->len + 2 ;
+      for( i = 0; i<a->size; i++ )
+        if( a->item[i].type != PIKE_T_STRING||a->item[i].u.string->size_shift )
+          error("Wrong argument type to make_http_headers("
+                "mapping(string(8bit):string(8bit)|"
+                "array(string(8bit))) heads)\n");
+        else
+          total_len += kl + a->item[i].u.string->len + 2;
+    } else
+      error("Wrong argument type to make_http_headers("
+            "mapping(string(8bit):string(8bit)|"
+            "array(string(8bit))) heads)\n");
+  }
+  total_len += 2;
+
+  res = begin_shared_string( total_len );
+  pnt = (char *)res->str;
+#define STRADD(X)\
+    for( l=X.u.string->len,s=X.u.string->str,c=0; c<l; c++ )\
+      *(pnt++)=*(s++);
+
+  NEW_MAPPING_LOOP( m->data )
+  {
+    char *s;
+    int l, c;
+    if( k->val.type == PIKE_T_STRING )
+    {
+      STRADD( k->ind ); *(pnt++) = ':'; *(pnt++) = ' ';
+      STRADD( k->val ); *(pnt++) = '\r'; *(pnt++) = '\n';
+    }
+    else
+    {
+      struct array *a = k->val.u.array;
+      int i, kl = k->ind.u.string->len + 2;
+      for( i = 0; i<a->size; i++ )
+      {
+        STRADD( k->ind );    *(pnt++) = ':'; *(pnt++) = ' ';
+        STRADD( a->item[i] );*(pnt++) = '\r';*(pnt++) = '\n';
+      }
+    }
+  }
+  *(pnt++) = '\r';
+  *(pnt++) = '\n';
+
+  pop_n_elems( args );
+  push_string( end_shared_string( res ) );
+}
+
+static void f_http_decode_string(INT32 args)
+{
+   int proc;
+   char *foo,*bar,*end;
+   struct pike_string *newstr;
+
+   if (!args || Pike_sp[-args].type != PIKE_T_STRING)
+     error("Invalid argument to http_decode_string(STRING);\n");
+
+   foo=bar=Pike_sp[-args].u.string->str;
+   end=foo+Pike_sp[-args].u.string->len;
+
+   /* count '%' characters */
+   for (proc=0; foo<end; ) if (*foo=='%') { proc++; foo+=3; } else foo++;
+
+   if (!proc) { pop_n_elems(args-1); return; }
+
+   /* new string len is (foo-bar)-proc*2 */
+   newstr=begin_shared_string((foo-bar)-proc*2);
+   foo=newstr->str;
+   for (proc=0; bar<end; foo++)
+      if (*bar=='%')
+      {
+        if (bar<end-2)
+          *foo=(((bar[1]<'A')?(bar[1]&15):((bar[1]+9)&15))<<4)|
+            ((bar[2]<'A')?(bar[2]&15):((bar[2]+9)&15));
+        else
+          *foo=0;
+        bar+=3;
+      }
+      else { *foo=*(bar++); }
+   pop_n_elems(args);
+   push_string(end_shared_string(newstr));
+}
+
+
+void pike_module_init()
+{
+  pike_add_function("make_http_headers", f_make_http_headers,
+               "function(mapping(string:string|array(string)):string)", 0 );
+
+  pike_add_function("http_decode_string", f_http_decode_string,
+               "function(string:string)", 0 );
+
+  start_new_program();
+  ADD_STORAGE( struct header_buf  );
+  pike_add_function( "feed", f_hp_feed, "function(string:array(string|mapping))",0 );
+  pike_add_function( "create", f_hp_create, "function(void:void)", 0 );
+  end_class( "HeaderParser", 0 );
+}
+
+void pike_module_exit()
+{
+}
-- 
GitLab