diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/lib.go b/lib.go index d714b6a..ba12705 100644 --- a/lib.go +++ b/lib.go @@ -1,5 +1,5 @@ -//package cwtch -package main +package cwtch +//package main import "C" import ( @@ -24,90 +24,96 @@ var application app.Application var acnQueue event.Queue var contactEventsQueue event.Queue -//export HelloWorld -func HelloWorld(a C.int, b C.int) C.int { - return a+b -} - -//export StartCwtch -func StartCwtch(dir_c *C.char, len C.int) { +//export c_StartCwtch +func c_StartCwtch(dir_c *C.char, len C.int, tor_c *C.char, torLen C.int) { dir := C.GoStringN(dir_c, len) - log.SetLevel(log.LevelDebug) - log.Infof("Loading Cwtch Directory %v", dir) - - mrand.Seed(int64(time.Now().Nanosecond())) - port := mrand.Intn(1000) + 9600 - controlPort := port + 1 - - // generate a random password (actually random, stored in memory, for the control port) - key := make([]byte, 64) - _, err := rand.Read(key) - if err != nil { - panic(err) - } - - log.Infof("making directory %v", dir) - os.MkdirAll(path.Join(dir, "/.tor","tor"),0700) - tor.NewTorrc().WithSocksPort(port).WithOnionTrafficOnly().WithControlPort(controlPort).WithHashedPassword(base64.StdEncoding.EncodeToString(key)).Build(filepath.Join(dir, ".tor", "tor", "torrc")) - acn, err := tor.NewTorACNWithAuth(path.Join(dir, "/.tor"), "", controlPort, tor.HashedPasswordAuthenticator{base64.StdEncoding.EncodeToString(key)}) - if err != nil { - log.Errorf("\nError connecting to Tor: %v\n", err) - } - //acn.WaitTillBootstrapped() - - - newApp := app.NewApp(acn, dir) - id := mrand.Int31() - acnQueue = event.NewQueue() - newApp.GetPrimaryBus().Subscribe(event.ACNStatus, acnQueue) - peer.DefaultEventsToHandle = []event.Type{ - event.EncryptedGroupMessage, - event.NewMessageFromPeer, - event.PeerAcknowledgement, - event.NewGroupInvite, - event.PeerError, - event.SendMessageToGroupError, - event.NewGetValMessageFromPeer, - event.PeerStateChange, - } - newApp.LoadProfiles("be gay do crime") - newApp.LaunchPeers() - application = newApp - log.Infof("Providing Handle %v", id) + tor := C.GoStringN(tor_c, torLen) + StartCwtch(dir, tor) } -//export ACNEvents -func ACNEvents() *C.char { +func StartCwtch(appDir string, torPath string) { + //go func (appDir string, torPath string) { + log.SetLevel(log.LevelDebug) + + log.Infof("Loading Cwtch Directory %v and tor path: %v", appDir, torPath) + + mrand.Seed(int64(time.Now().Nanosecond())) + port := mrand.Intn(1000) + 9600 + controlPort := port + 1 + + // generate a random password (actually random, stored in memory, for the control port) + key := make([]byte, 64) + _, err := rand.Read(key) + if err != nil { + panic(err) + } + + log.Infof("making directory %v", appDir) + os.MkdirAll(path.Join(appDir, "/.tor", "tor"), 0700) + tor.NewTorrc().WithSocksPort(port).WithOnionTrafficOnly().WithControlPort(controlPort).WithHashedPassword(base64.StdEncoding.EncodeToString(key)).Build(filepath.Join(appDir, ".tor", "tor", "torrc")) + acn, err := tor.NewTorACNWithAuth(path.Join(appDir, "/.tor"), torPath, controlPort, tor.HashedPasswordAuthenticator{base64.StdEncoding.EncodeToString(key)}) + if err != nil { + log.Errorf("\nError connecting to Tor: %v\n", err) + } + //acn.WaitTillBootstrapped() + + newApp := app.NewApp(acn, appDir) + acnQueue = event.NewQueue() + newApp.GetPrimaryBus().Subscribe(event.ACNStatus, acnQueue) + peer.DefaultEventsToHandle = []event.Type{ + event.EncryptedGroupMessage, + event.NewMessageFromPeer, + event.PeerAcknowledgement, + event.NewGroupInvite, + event.PeerError, + event.SendMessageToGroupError, + event.NewGetValMessageFromPeer, + event.PeerStateChange, + } + newApp.LoadProfiles("be gay do crime") + newApp.LaunchPeers() + application = newApp + //}(appDir, torPath) +} + +//export c_ACNEvents +func c_ACNEvents() *C.char { + return C.CString(ACNEvents()) +} + +func ACNEvents() string { select { case myevent := <- acnQueue.OutChan(): - return C.CString(fmt.Sprintf("%v", myevent)) + return fmt.Sprintf("%v", myevent) default: - return C.CString("") + return "" } } -//export NextEvent -func NextEvent() { - +//export c_GetProfiles +func c_GetProfiles() *C.char { + return C.CString(GetProfiles()) } -//export GetProfiles -func GetProfiles() *C.char { +func GetProfiles() string { profiles := application.ListPeers() jsonBytes,_ := json.Marshal(profiles) - return C.CString(string(jsonBytes)) + return string(jsonBytes) } + type Contact struct { Name string `json:"name"` Onion string `json:"onion"` Status string `json:"status"` } -//export GetContacts -func GetContacts(onion_ptr *C.char, onion_len C.int) *C.char { +//export c_GetContacts +func c_GetContacts(onion_ptr *C.char, onion_len C.int) *C.char { + return C.CString(GetContacts(C.GoStringN(onion_ptr, onion_len))) +} - onion := C.GoStringN(onion_ptr, onion_len) +func GetContacts(onion string)string { log.Infof("Get Contacts for %v", onion) mypeer := application.GetPeer(onion) @@ -122,48 +128,63 @@ func GetContacts(onion_ptr *C.char, onion_len C.int) *C.char { } bytes,_ := json.Marshal(contacts) - return C.CString(string(bytes)) + return string(bytes) } -//export SelectProfile -func SelectProfile(onion_ptr *C.char, onion_len C.int) *C.char { - onion := C.GoStringN(onion_ptr, onion_len) +//export c_SelectProfile +func c_SelectProfile(onion_ptr *C.char, onion_len C.int) *C.char { + return C.CString(SelectProfile(C.GoStringN(onion_ptr, onion_len))) +} + +func SelectProfile(onion string) string { log.Infof("Select Profile: %v", onion) contactEventsQueue = event.NewQueue() application.GetEventBus(onion).Subscribe(event.PeerStateChange, contactEventsQueue) - return C.CString("") + return "" } -//export ContactEvents -func ContactEvents() *C.char { +//export c_ContactEvents +func c_ContactEvents() *C.char { + return C.CString(ContactEvents()) +} + +func ContactEvents() string { select { case myevent := <- contactEventsQueue.OutChan(): - return C.CString(fmt.Sprintf("%v", myevent)) + return fmt.Sprintf("%v", myevent) default: - return C.CString("") + return "" } } -//export NumMessages -func NumMessages(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int) (n C.int) { +//export c_NumMessages +func c_NumMessages(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int) (n C.int) { profile := C.GoStringN(profile_ptr, profile_len) handle := C.GoStringN(handle_ptr, handle_len) - n = C.int(len(application.GetPeer(profile).GetContact(handle).Timeline.Messages)) + return C.int(NumMessages(profile, handle)) +} + +func NumMessages(profile, handle string) (n int) { + n = len(application.GetPeer(profile).GetContact(handle).Timeline.Messages) log.Infof("NumMessagse(%s, %s) = %d", profile, handle, n) return } -//export GetMessage -func GetMessage(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int, message_index C.int) *C.char { +//export c_GetMessage +func c_GetMessage(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int, message_index C.int) *C.char { profile := C.GoStringN(profile_ptr, profile_len) handle := C.GoStringN(handle_ptr, handle_len) + return C.CString(GetMessage(profile, handle, int(message_index))) +} + +func GetMessage(profile, handle string, message_index int) string { message := application.GetPeer(profile).GetContact(handle).Timeline.Messages[message_index] bytes,_ := json.Marshal(message) log.Infof("GetMessage(%s, %s, %d) = %s", profile, handle, message_index, string(bytes)) - return C.CString(string(bytes)) + return string(bytes) } // Leave as is, needed by ffi -func main() {} \ No newline at end of file +//func main() {} \ No newline at end of file