]> rtime.felk.cvut.cz Git - frescor/forb.git/commitdiff
Added initial work on inter-ORB communication
authorMichal Sojka <sojkam1@fel.cvut.cz>
Tue, 26 Aug 2008 16:01:32 +0000 (18:01 +0200)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Tue, 26 Aug 2008 16:01:32 +0000 (18:01 +0200)
14 files changed:
Makefile.omk
basic_types.h
conn.h [new file with mode: 0644]
forb-idl.idl
forb.c
forb.h
frescor.idl
iop.c [new file with mode: 0644]
iop.h [new file with mode: 0644]
proto.h [new file with mode: 0644]
sha1.c [new file with mode: 0644]
sha1.h [new file with mode: 0644]
uuid.c [new file with mode: 0644]
uuid.h [new file with mode: 0644]

index 70432338fef00cd256c966c2025e0421a4846abe..a8282f6301cfb55187c8ad859d87f242a4bf54a5 100644 (file)
@@ -1,12 +1,15 @@
 SUBDIRS = ulut fosa forb-idl tests-idl tests\r
 \r
 lib_LIBRARIES = forb\r
-forb_SOURCES = forb.c cdr.c\r
+forb_SOURCES = forb.c cdr.c sha1.c uuid.c\r
+forb_CLIENT_IDL = forb-idl.idl\r
 \r
 to_forb_subdir=$(1)->forb/$(1)\r
 renamed_include_HEADERS = \\r
        $(call to_forb_subdir,forb.h) \\r
        $(call to_forb_subdir,basic_types.h) \\r
-       $(call to_forb_subdir,cdr.h)\r
+       $(call to_forb_subdir,cdr.h) \\r
+       $(call to_forb_subdir,uuid.h)\r
 \r
-#include_HEADERS = forb_config.h\r
+renamed_include_GEN_HEADERS = \\r
+       $(call to_forb_subdir,forb-idl.h)\r
index 9bd8e30fe2f204c0b337b616ea573ed6875dbab5..4d00372561d850125537e05b0a7674a30b3e6d50 100644 (file)
@@ -10,8 +10,10 @@ enum {
 
 typedef int16_t   CORBA_short;
 typedef int32_t   CORBA_long;
+typedef int64_t   CORBA_long_long;
 typedef uint16_t  CORBA_unsigned_short;
 typedef uint32_t  CORBA_unsigned_long;
+typedef uint64_t  CORBA_unsigned_long_long;
 typedef float     CORBA_float;
 typedef double    CORBA_double;
 typedef char     CORBA_char;
diff --git a/conn.h b/conn.h
new file mode 100644 (file)
index 0000000..adf99b9
--- /dev/null
+++ b/conn.h
@@ -0,0 +1,13 @@
+#ifndef FORB_CONN_H
+#define FORB_CONN_H
+
+#include <forb/proto.h>
+#include <forb/uuid.h>
+
+/** Connection to another FORB */
+typedef struct forb_conn {
+       forb_uuid_t uuid;       /**< Other side's UUID */
+       forb_proto_t *proto;    /**< Protocol to use */
+} forb_conn_t;
+
+#endif
index 2215b135716849dd8ba1ba3a5507fdd24238eea5..9eadede4f081b59a19f983888da14f399bfaf3d8 100644 (file)
@@ -1,13 +1,13 @@
 module forb {
+       typedef long long object_key;
 
        // Inter-ORB protocol
        module iop {
-               typedef long long object_key;
                
-               enum message_type {
-                       REQUEST,
-                       REPLY
-               };
+               typedef octet message_type;
+
+               const message_type REQUEST = 0;
+               const message_type REPLY   = 1;
 
                struct version {
                        octet major, minor;
@@ -18,20 +18,27 @@ module forb {
                const message_flags LITTLE_ENDIAN = 1;
 
                struct message_header {
-                       version proto_version;
-                        octet message_type;
+                       version       proto_version;
+                        message_type  message_type;
                        message_flags flags;
                        unsigned long message_size;
                };
+               const long MESSAGE_HEADER_SIZE = 8;
+               
                struct request_header {
+                       unsigned long request_id;
+                       string iface;
                        object_key objkey;
                        short method_index;
                };
+               const long REQUEST_HEADER_SIZE = 8;
+
                typedef short reply_flags;
                const reply_flags FLAG_EX = 1;
                struct reply_header {
                        unsigned short flags;
                };
+               const long REPLY_HEADER_SIZE = 8;
        };
        
        __declspec(pidl) interface orb {
diff --git a/forb.c b/forb.c
index d938bf6dd7d8d988b611e48e9ef45830d4cf7b50..6f838f5e93d74af41ebe3e3f11f4fc8a2dae1ca6 100644 (file)
--- a/forb.c
+++ b/forb.c
@@ -1,14 +1,42 @@
-#include "forb.h"
+#include <forb/forb.h>
 #include <string.h>
 #include <ul_gavl.h>
+#include <forb/uuid.h>
 
 static struct gavl_root type_registry;
 
+typedef struct forb_rt {
+} forb_rt;
+
+typedef struct forb_orb_data {
+       forb_uuid_t uuid;
+       forb_rt rt;             /**< Routing table */
+} forb_orb_data;
+
 forb_orb forb_init(void)
 {
+       forb_orb orb;
+       forb_orb_data *d;
+       orb = forb_malloc(sizeof(*orb));
+       if (!orb) goto err;
+       d = forb_malloc(sizeof(forb_orb_data));
+       if (!d) goto err1;
+       orb->instance_data = d;
+       forb_uuid_generate(&d->uuid);
+
+       return orb;
+err1:
+       forb_free(orb);
+err:
        return NULL;
 }
 
+void forb_destroy(forb_orb orb)
+{
+       forb_free(orb->instance_data);
+       forb_free(orb);
+}
+
 void
 forb_register_interface(const struct forb_interface *interface)
 {
@@ -19,6 +47,7 @@ forb_register_interface(const struct forb_interface *interface)
 void
 forb_send_request(forb_object obj, unsigned method_index, CDR_Codec *codec, forb_request_handle_t *req, CORBA_Environment *env)
 {
+       
 }
 
 void
diff --git a/forb.h b/forb.h
index e97374419278f5a9ec39dd5d28447bc1a6defac9..26e73920ecd9733a264449db9e2a16003288b740 100644 (file)
--- a/forb.h
+++ b/forb.h
@@ -48,6 +48,14 @@ struct forb_server {
 
 struct forb_object;
 
+/** Opaque object reference type. */
+typedef struct forb_object *forb_object;
+typedef forb_object CORBA_Object;
+
+/** Object reference type for ORB pseudo object. */
+typedef forb_object forb_orb;
+
+
 typedef void (*forb_skel_func)(CDR_Codec *cin,
                               CDR_Codec *cout,
                               struct forb_object *obj,
@@ -60,17 +68,22 @@ struct forb_interface {
        uint32_t type_hash;
 };
 
+/** Object reference structure */
 struct forb_object {
+       /**< Any data for implementation (in server) */
        void *instance_data;
-       /** Interface (for servers); FIXME: What about clients? */
+
+       /** Description of interface implemented by this object (for
+        * servers); FIXME: What about clients? */
        const struct forb_interface *interface;
+
        struct forb_server *server;
+
        /** Pointer to the object implementation methods or NULL in
         * case of remote object. */
        const void *implementation;
+       forb_orb orb;           /**< ORB reference */
 };
-typedef struct forb_object *forb_object;
-typedef forb_object CORBA_Object;
 
 #define forb_instance_data(obj) ((obj)->instance_data)
 
@@ -84,10 +97,19 @@ typedef struct forb_request_handle {
 } forb_request_handle_t;
 
 
-typedef forb_object forb_orb;
+/** 
+ * Initializes FORB. This function has to be called before any other
+ * FORB function.
+ * @return FORB object reference of NULL in case of error.
+ */
+forb_orb forb_init(void);
 
-forb_orb
-forb_init(void);
+/** 
+ * Deallocates all resources consumed by FORB.
+ * 
+ * @param orb FORB object reference to destroy.
+ */
+void forb_destroy(forb_orb orb);
 
 #define forb_malloc(size) malloc(size)
 #define forb_free(ptr) free(ptr)
index 2cdf58a5a6b325e2dee7bcc04d44623c6035f227..2c35522100096be58516aea6b93eda48264aef96 100644 (file)
@@ -1,3 +1,59 @@
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners:                //
+//                                                                       //
+//   Universidad de Cantabria,              SPAIN                        //
+//   University of York,                    UK                           //
+//   Scuola Superiore Sant'Anna,            ITALY                        //
+//   Kaiserslautern University,             GERMANY                      //
+//   Univ. Politécnica  Valencia,           SPAIN                       //
+//   Czech Technical University in Prague,  CZECH REPUBLIC               //
+//   ENEA                                   SWEDEN                       //
+//   Thales Communication S.A.              FRANCE                       //
+//   Visual Tools S.A.                      SPAIN                        //
+//   Rapita Systems Ltd                     UK                           //
+//   Evidence                               ITALY                        //
+//                                                                       //
+//   See http://www.frescor.org for a link to partners' websites         //
+//                                                                       //
+//          FRESCOR project (FP6/2005/IST/5-034026) is funded            //
+//       in part by the European Union Sixth Framework Programme         //
+//       The European Union is not liable of any use that may be         //
+//       made of this code.                                              //
+//                                                                       //
+//                                                                       //
+// based on previous work (FSF) done in the FIRST project                //
+//                                                                       //
+//  Copyright (C) 2005  Mälardalen University, SWEDEN                   //
+//                      Scuola Superiore S.Anna, ITALY                   //
+//                      Universidad de Cantabria, SPAIN                          //
+//                      University of York, UK                           //
+//                                                                       //
+//  FSF API web pages: http:marte.unican.es/fsf/docs                     //
+//                     http:shark.sssup.it/contrib/first/docs/           //
+//                                                                       //
+//  This file is part of FORB (Frescor Object Request Broker)            //
+//                                                                       //
+// FORB is free software; you can redistribute it and/or modify it       //
+// under terms of the GNU General Public License as published by the     //
+// Free Software Foundation; either version 2, or (at your option) any   //
+// later version.  FORB 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 FORB; see file      //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  //
+// Cambridge, MA 02139, USA.                                             //
+//                                                                       //
+// As a special exception, including FORB header files in a file,        //
+// instantiating FORB generics or templates, or linking other files      //
+// with FORB objects to produce an executable application, does not      //
+// by itself cause the resulting executable application to be covered    //
+// by the GNU General Public License. This exception does not            //
+// however invalidate any other reasons why the executable file might be  //
+// covered by the GNU Public License.                                    //
+////////////////////////////////////////////////////////////////////////////
+                                                               
 module frsh {
        struct timespec {
                long tv_sec;
@@ -38,4 +94,14 @@ module frsh {
                long commit_contract(in contract_handle_t handle);
                long cancel_contract(in contract_handle_t handle);
        };
+
+       interface resource_schduler {
+               long create_vres(in contract_t contract);
+               long change_vres(in contract_handle_t handle);
+               long cancel_vres(in contract_handle_t handle);
+       };
+
+       interface dtm {
+               long get_contract(in contract_handle_t handle);
+       };
 };
diff --git a/iop.c b/iop.c
new file mode 100644 (file)
index 0000000..65adb50
--- /dev/null
+++ b/iop.c
@@ -0,0 +1,78 @@
+#include <forb/iop.h>
+#include <forb/forb-idl.h>
+
+#define VER_MAJOR 0
+#define VER_MINOR 0
+
+#define VER(major, minor) ((major)<<8 || (minor))
+
+CORBA_boolean
+forb_iop_prepend_message_header(CDR_Codec *codec, forb_iop_message_type mt)
+{
+       CORBA_boolean ret;
+       forb_iop_message_header mh;
+       mh.proto_version.major = VER_MAJOR;
+       mh.proto_version.minor = VER_MINOR;
+       mh.message_type = mt;
+       mh.flags = (codec->data_endian == LittleEndian) ? forb_iop_LITTLE_ENDIAN : 0;
+       mh.message_size = CDR_data_size(codec);
+       ret = CDR_buffer_prepend(codec, forb_iop_MESSAGE_HEADER_SIZE);
+       if (ret) {
+               ret = forb_iop_message_header_serialize(codec, &mh);
+       }
+       return ret;
+}
+
+CORBA_boolean
+forb_iop_prepend_request_header(CDR_Codec *codec, forb_iop_message_type mt)
+{
+       CORBA_boolean ret;
+       forb_iop_request_header rh;
+       ret = CDR_buffer_prepend(codec, forb_iop_REQUEST_HEADER_SIZE);
+       if (ret) {
+               ret = forb_iop_request_header_serialize(codec, &mh);
+       }
+       return ret;
+}
+
+static void
+process_request(CDR_Codec *codec)
+{
+       forb_iop_request_header rh;
+       forb_iop_request_header_deserialize(codec, &rh);
+}
+
+static void
+process_message(CDR_Codec *codec, forb_iop_message_header *mh)
+{
+       switch (mh.message_type) {
+               case forb_iop_REQUEST:
+                       process_request(codec);
+                       break;
+               case forb_iop_REPLY:
+                       process_reply(codec);
+                       break;
+               default:
+                       break;
+       }
+}
+
+void
+forb_iop_process_packet(CDR_Codec *codec)
+{
+       forb_iop_message_header mh;
+       forb_iop_version_deserialize(codec, &mh.proto_version);
+       switch (VER(mh.proto_version.major, mh.proto_version.minor)) {
+               case VER_SHORT(VER_MAJOR, VER_MINOR):
+                       forb_iop_message_type_deserialize(codec, &mh.message_type);
+                       forb_iop_message_flags_deserialize(codec, &mh.message_flags);
+                       codec->data_endian = (flags && forb_iop_LITTLE_ENDIAN) ?
+                               LittleEndian : BigEndian;                       
+                       CORBA_unsigned_long_deserialize(codec, &mh.message_size);
+                       process_message(codec, &mh);
+                       break;
+               default:
+                       /* TODO: Handle mismatches */
+                       break;
+       }
+}
diff --git a/iop.h b/iop.h
new file mode 100644 (file)
index 0000000..7237d52
--- /dev/null
+++ b/iop.h
@@ -0,0 +1,9 @@
+#ifndef FORB_IOP_H
+#define FORB_IOP_H
+
+#include <cdr.h>
+
+CORBA_boolean
+forb_iop_prepend_message_header(CDR_Codec *codec, forb_iop_message_type mt);
+
+#endif
diff --git a/proto.h b/proto.h
new file mode 100644 (file)
index 0000000..d762458
--- /dev/null
+++ b/proto.h
@@ -0,0 +1,7 @@
+#ifndef FORB_PROTO_H
+#define FORB_PROTO_H
+
+typedef struct forb_proto {
+} forb_proto_t;
+
+#endif
diff --git a/sha1.c b/sha1.c
new file mode 100644 (file)
index 0000000..63dc8e0
--- /dev/null
+++ b/sha1.c
@@ -0,0 +1,225 @@
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+/* #define LITTLE_ENDIAN * This should be #define'd if true. */
+/* #define SHA1HANDSOFF * Copies data before messing with it. */
+
+/* #include <stdio.h> */
+#include <string.h>
+
+/* Extract endinaning from glibc */
+#include <endian.h>
+#undef LITTLE_ENDIAN
+#ifdef __BYTE_ORDER
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define LITTLE_ENDIAN
+#endif
+#endif
+
+typedef struct {
+    unsigned long state[5];
+    unsigned long count[2];
+    unsigned char buffer[64];
+} SHA1_CTX;
+
+void SHA1Transform(unsigned long state[5], unsigned char buffer[64]);
+void SHA1Init(SHA1_CTX* context);
+void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len);
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifdef LITTLE_ENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+    |(rol(block->l[i],8)&0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+    ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void SHA1Transform(unsigned long state[5], unsigned char buffer[64])
+{
+unsigned long a, b, c, d, e;
+typedef union {
+    unsigned char c[64];
+    unsigned long l[16];
+} CHAR64LONG16;
+CHAR64LONG16* block;
+#ifdef SHA1HANDSOFF
+static unsigned char workspace[64];
+    block = (CHAR64LONG16*)workspace;
+    memcpy(block, buffer, 64);
+#else
+    block = (CHAR64LONG16*)buffer;
+#endif
+    /* Copy context->state[] to working vars */
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[3];
+    e = state[4];
+    /* 4 rounds of 20 operations each. Loop unrolled. */
+    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+    /* Add the working vars back into context.state[] */
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+    state[4] += e;
+    /* Wipe variables */
+    a = b = c = d = e = 0;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(SHA1_CTX* context)
+{
+    /* SHA1 initialization constants */
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xEFCDAB89;
+    context->state[2] = 0x98BADCFE;
+    context->state[3] = 0x10325476;
+    context->state[4] = 0xC3D2E1F0;
+    context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len)
+{
+unsigned int i, j;
+
+    j = (context->count[0] >> 3) & 63;
+    if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
+    context->count[1] += (len >> 29);
+    if ((j + len) > 63) {
+        memcpy(&context->buffer[j], data, (i = 64-j));
+        SHA1Transform(context->state, context->buffer);
+        for ( ; i + 63 < len; i += 64) {
+            SHA1Transform(context->state, &data[i]);
+        }
+        j = 0;
+    }
+    else i = 0;
+    memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
+{
+unsigned long i, j;
+unsigned char finalcount[8];
+
+    for (i = 0; i < 8; i++) {
+        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
+         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
+    }
+    SHA1Update(context, (unsigned char *)"\200", 1);
+    while ((context->count[0] & 504) != 448) {
+        SHA1Update(context, (unsigned char *)"\0", 1);
+    }
+    SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
+    for (i = 0; i < 20; i++) {
+        digest[i] = (unsigned char)
+         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+    }
+    /* Wipe variables */
+    i = j = 0;
+    memset(context->buffer, 0, 64);
+    memset(context->state, 0, 20);
+    memset(context->count, 0, 8);
+    memset(&finalcount, 0, 8);
+#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */
+    SHA1Transform(context->state, context->buffer);
+#endif
+}
+
+
+/*************************************************************/
+
+#if 0
+int main(int argc, char** argv)
+{
+int i, j;
+SHA1_CTX context;
+unsigned char digest[20], buffer[16384];
+FILE* file;
+
+    if (argc > 2) {
+        puts("Public domain SHA-1 implementation - by Steve Reid <steve@edmweb.com>");
+        puts("Produces the SHA-1 hash of a file, or stdin if no file is specified.");
+        exit(0);
+    }
+    if (argc < 2) {
+        file = stdin;
+    }
+    else {
+        if (!(file = fopen(argv[1], "rb"))) {
+            fputs("Unable to open file.", stderr);
+            exit(-1);
+        }
+    } 
+    SHA1Init(&context);
+    while (!feof(file)) {  /* note: what if ferror(file) */
+        i = fread(buffer, 1, 16384, file);
+        SHA1Update(&context, buffer, i);
+    }
+    SHA1Final(digest, &context);
+    fclose(file);
+    for (i = 0; i < 5; i++) {
+        for (j = 0; j < 4; j++) {
+            printf("%02X", digest[i*4+j]);
+        }
+        putchar(' ');
+    }
+    putchar('\n');
+    exit(0);
+}
+#endif
diff --git a/sha1.h b/sha1.h
new file mode 100644 (file)
index 0000000..fb67571
--- /dev/null
+++ b/sha1.h
@@ -0,0 +1,16 @@
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+*/
+
+typedef struct {
+    unsigned long state[5];
+    unsigned long count[2];
+    unsigned char buffer[64];
+} SHA1_CTX;
+
+void SHA1Transform(unsigned long state[5], unsigned char buffer[64]);
+void SHA1Init(SHA1_CTX* context);
+void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len);
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
diff --git a/uuid.c b/uuid.c
new file mode 100644 (file)
index 0000000..14d3e73
--- /dev/null
+++ b/uuid.c
@@ -0,0 +1,37 @@
+/**
+ * @file   uuid.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Tue Aug 26 09:17:31 2008
+ * 
+ * @brief  Unix version of UUID generator
+ * 
+ */
+#include <forb/uuid.h>
+#include <time.h>
+#include "sha1.h"
+#include <sys/types.h>
+#include <unistd.h>
+
+/** 
+ * Generates universally unique ID.
+ * 
+ * @param dest Where to store the newly generated UUID.
+ * 
+ * @return Same as @a dest.
+ */
+forb_uuid_t *forb_uuid_generate(forb_uuid_t *dest)
+{
+       SHA1_CTX ctx;
+       time_t t = time(0);;
+       pid_t pid = getpid();
+       unsigned char digest[20];
+       
+       SHA1Init(&ctx);
+       SHA1Update(&ctx, (unsigned char*)&t, sizeof(t));
+       SHA1Update(&ctx, (unsigned char*)&pid, sizeof(pid));
+       /* This should be enough for localhost process.
+        * TODO: Add network addresses for distributed operation! */
+       SHA1Final(digest, &ctx);
+       memcpy(dest, digest, sizeof(forb_uuid_t));
+       return dest;
+}
diff --git a/uuid.h b/uuid.h
new file mode 100644 (file)
index 0000000..a51d021
--- /dev/null
+++ b/uuid.h
@@ -0,0 +1,20 @@
+#ifndef FORB_UUID_H
+#define FORB_UUID_H
+
+#include <string.h>
+
+/**
+ * Universally unique ID type.
+ */
+typedef struct {
+       char byte[8];
+} forb_uuid_t;
+
+static inline int forb_uuid_cmp(forb_uuid_t u1, forb_uuid_t u2)
+{
+       return memcmp(&u1, &u2, sizeof(forb_uuid_t));
+}
+
+forb_uuid_t *forb_uuid_generate(forb_uuid_t *dest);
+
+#endif