Adding zeroc ice interface for notifications
diff --git a/ice_cxx.py b/ice_cxx.py
new file mode 100644
index 0000000..54d9386
--- /dev/null
+++ b/ice_cxx.py
@@ -0,0 +1,57 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+#!/usr/bin/env python
+# encoding: utf-8
+# Alexander Afanasyev, 2013
+
+from waflib.Task import Task
+from waflib.TaskGen import extension 
+
+"""
+A simple tool to integrate zeroc ICE into your build system.
+
+    def configure(conf):
+        conf.load('compiler_cxx cxx ice_cxx')
+
+    def build(bld):
+        bld(
+                features = 'cxx cxxprogram'
+                source   = 'main.cpp file1.ice', 
+                include  = '.',
+                target   = 'executable') 
+
+"""
+
+class ice_cxx(Task):
+        run_str = '${SLICE2CPP} --header-ext ice.h --source-ext ice.cc --output-dir ${SRC[0].parent.get_bld().abspath()}  ${SRC[0].abspath()}'
+	color   = 'BLUE'
+	ext_out = ['.ice.h', '.ice.cc']
+
+@extension('.ice')
+def process_protoc(self, node):
+	cpp_node = node.change_ext('.ice.cc')
+	hpp_node = node.change_ext('.ice.h')
+	self.create_task('ice_cxx', node, [cpp_node, hpp_node])
+	self.source.append(cpp_node)
+
+	use = getattr(self, 'use', '')
+	if not 'ICE' in use:
+		self.use = self.to_list(use) + ['ICE']
+
+ICE_PATHS = ['/usr', '/usr/local', '/opt/local', '/sw']
+
+def options(opt):
+        opt.add_option('--ice',action='store',dest='ICE_PATH',help='''path to ZeroC installation''')
+        
+
+def configure(conf):
+        # conf.check_cfg(package="", uselib_store="PROTOBUF", args=['--cflags', '--libs'])
+        if conf.options.ICE_PATH:
+                conf.find_program('slice2cpp', var='SLICE2CPP', path_list="%s/bin" % conf.options.ICE_PATH, mandatory=True)
+        else:
+                conf.find_program('slice2cpp', var='SLICE2CPP', path_list=["%s/bin" % path for path in ICE_PATHS], mandatory=True)
+        
+        conf.env['LIB_ICE'] = ["ZeroCIce", "IceUtil"]
+        # self.env['LIBPATH_ICE'] = ""
+        # self.env['CXXFLAGS_ICE'] = ""
+	
+
diff --git a/src/chronoshare-client.ice b/src/chronoshare-client.ice
new file mode 100644
index 0000000..f32577e
--- /dev/null
+++ b/src/chronoshare-client.ice
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ *	   Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ */
+
+module ChronoshareClient
+{
+  sequence<byte> HashBytes;
+  
+  interface Notify 
+  {
+    void updateFile (string filename, HashBytes fileHash, string atime, string mtime, string ctime, int mode);
+
+    void deleteFile (string filename);
+  };
+};
diff --git a/src/db-helper.cc b/src/db-helper.cc
index 334621e..f6d7ba8 100644
--- a/src/db-helper.cc
+++ b/src/db-helper.cc
@@ -34,64 +34,98 @@
 using namespace boost;
 
 const std::string INIT_DATABASE = "\
-PRAGMA foreign_keys = ON;                                       \
-                                                                \
-CREATE TABLE                                                    \
-    SyncNodes(                                                  \
-        device_id       INTEGER PRIMARY KEY AUTOINCREMENT,      \
-        device_name     TEXT NOT NULL,                          \
-        description     TEXT,                                   \
-        seq_no          INTEGER NOT NULL,                       \
-        last_known_tdi  TEXT,                                   \
-        last_update     TIMESTAMP                               \
-    );                                                          \
-                                                                \
-CREATE TRIGGER SyncNodesUpdater_trigger                                \
-    BEFORE INSERT ON SyncNodes                                         \
-    FOR EACH ROW                                                       \
-    WHEN (SELECT device_id                                             \
-             FROM SyncNodes                                            \
-             WHERE device_name=NEW.device_name)                        \
-         IS NOT NULL                                                   \
-    BEGIN                                                              \
-        UPDATE SyncNodes                                               \
-            SET seq_no=max(seq_no,NEW.seq_no)                          \
-            WHERE device_name=NEW.device_name;                         \
-        SELECT RAISE(IGNORE);                                          \
-    END;                                                               \
-                                                                       \
-CREATE INDEX SyncNodes_device_name ON SyncNodes (device_name);         \
-                                                                       \
-CREATE TABLE SyncLog(                                                  \
-        state_id    INTEGER PRIMARY KEY AUTOINCREMENT,                 \
-        state_hash  BLOB NOT NULL UNIQUE,                              \
-        last_update TIMESTAMP NOT NULL                                 \
-    );                                                                 \
-                                                                       \
-CREATE TABLE                                                            \
-    SyncStateNodes(                                                     \
-        id          INTEGER PRIMARY KEY AUTOINCREMENT,                  \
-        state_id    INTEGER NOT NULL                                    \
-            REFERENCES SyncLog (state_id) ON UPDATE CASCADE ON DELETE CASCADE, \
-        device_id   INTEGER NOT NULL                                    \
-            REFERENCES SyncNodes (device_id) ON UPDATE CASCADE ON DELETE CASCADE, \
-        seq_no      INTEGER NOT NULL                                    \
-    );                                                                  \
-                                                                        \
-CREATE INDEX SyncStateNodes_device_id ON SyncStateNodes (device_id);    \
-CREATE INDEX SyncStateNodes_state_id  ON SyncStateNodes (state_id);  \
-CREATE INDEX SyncStateNodes_seq_no    ON SyncStateNodes (seq_no);          \
-                                                                        \
-CREATE TRIGGER SyncLogGuard_trigger                                     \
-    BEFORE INSERT ON SyncLog                                            \
-    FOR EACH ROW                                                        \
-    WHEN (SELECT state_hash                                             \
-            FROM SyncLog                                                \
-            WHERE state_hash=NEW.state_hash)                            \
-        IS NOT NULL                                                     \
-    BEGIN                                                               \
-        DELETE FROM SyncLog WHERE state_hash=NEW.state_hash;            \
-    END;                                                                \
+PRAGMA foreign_keys = ON;                                       \n\
+                                                                \n\
+CREATE TABLE                                                    \n\
+    SyncNodes(                                                  \n\
+        device_id       INTEGER PRIMARY KEY AUTOINCREMENT,      \n\
+        device_name     TEXT NOT NULL,                          \n\
+        description     TEXT,                                   \n\
+        seq_no          INTEGER NOT NULL,                       \n\
+        last_known_tdi  TEXT,                                   \n\
+        last_update     TIMESTAMP                               \n\
+    );                                                          \n\
+                                                                \n\
+CREATE TRIGGER SyncNodesUpdater_trigger                                \n\
+    BEFORE INSERT ON SyncNodes                                         \n\
+    FOR EACH ROW                                                       \n\
+    WHEN (SELECT device_id                                             \n\
+             FROM SyncNodes                                            \n\
+             WHERE device_name=NEW.device_name)                        \n\
+         IS NOT NULL                                                   \n\
+    BEGIN                                                              \n\
+        UPDATE SyncNodes                                               \n\
+            SET seq_no=max(seq_no,NEW.seq_no)                          \n\
+            WHERE device_name=NEW.device_name;                         \n\
+        SELECT RAISE(IGNORE);                                          \n\
+    END;                                                               \n\
+                                                                       \n\
+CREATE INDEX SyncNodes_device_name ON SyncNodes (device_name);         \n\
+                                                                       \n\
+CREATE TABLE SyncLog(                                                  \n\
+        state_id    INTEGER PRIMARY KEY AUTOINCREMENT,                 \n\
+        state_hash  BLOB NOT NULL UNIQUE,                              \n\
+        last_update TIMESTAMP NOT NULL                                 \n\
+    );                                                                 \n\
+                                                                       \n\
+CREATE TABLE                                                            \n\
+    SyncStateNodes(                                                     \n\
+        id          INTEGER PRIMARY KEY AUTOINCREMENT,                  \n\
+        state_id    INTEGER NOT NULL                                    \n\
+            REFERENCES SyncLog (state_id) ON UPDATE CASCADE ON DELETE CASCADE, \n\
+        device_id   INTEGER NOT NULL                                    \n\
+            REFERENCES SyncNodes (device_id) ON UPDATE CASCADE ON DELETE CASCADE, \n\
+        seq_no      INTEGER NOT NULL                                    \n\
+    );                                                                  \n\
+                                                                        \n\
+CREATE INDEX SyncStateNodes_device_id ON SyncStateNodes (device_id);    \n\
+CREATE INDEX SyncStateNodes_state_id  ON SyncStateNodes (state_id);     \n\
+CREATE INDEX SyncStateNodes_seq_no    ON SyncStateNodes (seq_no);       \n\
+                                                                        \n\
+CREATE TRIGGER SyncLogGuard_trigger                                     \n\
+    BEFORE INSERT ON SyncLog                                            \n\
+    FOR EACH ROW                                                        \n\
+    WHEN (SELECT state_hash                                             \n\
+            FROM SyncLog                                                \n\
+            WHERE state_hash=NEW.state_hash)                            \n\
+        IS NOT NULL                                                     \n\
+    BEGIN                                                               \n\
+        DELETE FROM SyncLog WHERE state_hash=NEW.state_hash;            \n\
+    END;                                                                \n\
+                                                                        \n\
+CREATE TABLE ActionLog (                                                \n\
+    device_id   INTEGER NOT NULL,                                       \n\
+    seq_no      INTEGER NOT NULL,                                       \n\
+                                                                        \n\
+    action      CHAR(1) NOT NULL, /* 0 for \"update\", 1 for \"delete\". */ \n\
+    filename    TEXT NOT NULL,                                          \n\
+                                                                        \n\
+    version     INTEGER NOT NULL,                                       \n\
+    action_timestamp TIMESTAMP NOT NULL,                                \n\
+                                                                        \n\
+    file_hash   BLOB, /* NULL if action is \"delete\" */                \n\
+    file_atime  TIMESTAMP,                                              \n\
+    file_mtime  TIMESTAMP,                                              \n\
+    file_ctime  TIMESTAMP,                                              \n\
+    file_chmod  INTEGER,                                                \n\
+                                                                        \n\
+    parent_device_id INTEGER,                                           \n\
+    parent_seq_no    INTEGER,                                           \n\
+                                                                        \n\
+    action_name	     TEXT NOT NULL,                                     \n\
+    action_content_object BLOB NOT NULL,                                \n\
+                                                                        \n\
+    PRIMARY KEY (device_id, seq_no),                                    \n\
+                                                                        \n\
+    FOREIGN KEY (parent_device_id, parent_seq_no)                       \n\
+	REFERENCES ActionLog (device_id, parent_seq_no)                 \n\
+	ON UPDATE RESTRICT                                              \n\
+	ON DELETE SET NULL                                              \n\
+);                                                                      \n\
+                                                                        \n\
+CREATE INDEX ActionLog_filename_version ON ActionLog (filename,version);        \n\
+CREATE INDEX ActionLog_parent ON ActionLog (parent_device_id, parent_seq_no);   \n\
+CREATE INDEX ActionLog_action_name ON ActionLog (action_name);          \n\
 ";
 
 DbHelper::DbHelper (const std::string &path)
diff --git a/src/main.cc b/src/main.cc
index d1d53c9..ba1fecc 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -15,9 +15,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- *         Chaoyi Bian <bcy@pku.edu.cn>
- *	   Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ *	   Zhenkai Zhu <zhenkai@cs.ucla.edu>
  */
 
 #include "db-helper.h"
diff --git a/wscript b/wscript
index d9fbce6..c8f63ad 100644
--- a/wscript
+++ b/wscript
@@ -12,6 +12,7 @@
     opt.add_option('--yes',action='store_true',default=False) # for autoconf/automake/make compatibility
 
     opt.load('compiler_cxx boost ccnx protoc')
+    opt.load('ice_cxx', tooldir=["."])
 
 def configure(conf):
     conf.load("compiler_cxx")
@@ -50,7 +51,8 @@
       conf.define('_TEST', 1)
 
     conf.load('protoc')
-
+    conf.load('ice_cxx')
+    
     conf.write_config_header('src/config.h')
 
 def build (bld):
@@ -83,7 +85,8 @@
         # source = bld.path.ant_glob(['src/**/*.cc']),
         source = ['src/main.cc', 
                   'src/db-helper.cc',
-                  'src/hash-string-converter.cc'],
+                  'src/hash-string-converter.cc',
+                  'src/chronoshare-client.ice'],
         use = 'BOOST BOOST_IOSTREAMS BOOST_REGEX CCNX SSL SQLITE3',
         includes = ['include', 'src'],
         )