/* * Copyright (c) 2001 Tommy Bohlin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* irs.c */ #include #include #include #include #include #include #include #include #include #include #include static int verbosity; static int port; static char *host = "localhost"; /********************************************************************** * OBEX server **********************************************************************/ static void objectToFile(OBEXServer* os, void* buf, int len) { int i; char fname[32]; FILE* f; for(i=0;;i++) { bool ok=TRUE; DIR *dir=opendir("."); struct dirent* de; sprintf(fname,"%d.obex",i); while((de=readdir(dir))) { if(!strcmp(fname,de->d_name)) { ok=FALSE; break; } } closedir(dir); if(ok) break; } birda_log("object %s\n",fname); f=fopen(fname,"w"); fwrite(buf,1,len,f); fclose(f); } int in_address(char *host, short port, struct sockaddr_in *address ) { #define HOST_NAME_LEN 128 char host_name[HOST_NAME_LEN] ; char *the_host; struct hostent *hp; bzero((char *)address, sizeof(*address)); /* * Determine the host name */ if (host == NULL) { (void)gethostname(host_name, HOST_NAME_LEN); the_host = host_name; } else the_host = host; #if 0 if (is_number_address(host)) address->sin_addr.s_addr = inet_addr(host); #endif if ((hp = gethostbyname(the_host)) == NULL) { birda_log("Cannot send obex object to socket: %s\n", strerror(errno)); return -1; } bcopy(hp->h_addr, (char *)&address->sin_addr, hp->h_length); address->sin_family = AF_INET; address->sin_port = htons(port); return 0; } static void objectToSocket(OBEXServer* os, void* buf, int len) { int s, n, offset = 0; struct sockaddr_in sa; u_char *cbuf = buf; birda_log("sending obex object to port %d\n", port); if (in_address(host, port, &sa) < 0 || (s = socket(PF_INET, SOCK_STREAM, 0)) < 0 || connect(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) { birda_log("Cannot send obex object to socket: %s\n", strerror(errno)); return; } while ((n = write(s, &cbuf[offset], len - offset)) > 0) { offset += n; } close(s); } /********************************************************************** * COMM server **********************************************************************/ static void input(void* handle) { COMMPort* cp=(COMMPort*)handle; u_char buf[1024]; int len=read(fileno(stdin),buf,sizeof buf); if (len == 0) { if(verbosity>0) birda_log("comm select with no data to read, closing connection\n"); evtRemoveSource(fileno(stdin)); return; } #if 0 { int ix; birda_log("pc -> palm: len=%d\n", len); for (ix = 0; ix < len; ix++) { birda_log("%02x ", buf[ix]); } birda_log("\n"); } #endif if(len>0) commPortWrite(cp,buf,len); } static void commStatus(COMMPort* comm, int event) { switch(event) { case COMM_CONNECTED: if(verbosity>0) birda_log("comm connected\n"); evtAddSource(fileno(stdin),input,comm); break; case COMM_DISCONNECTED: evtRemoveSource(fileno(stdin)); if(verbosity>0) birda_log("comm disconnected\n"); break; } } static void commData(COMMPort* comm, void* buf, int len) { #if 0 birda_log("palm -> pc: len=%d\n", len); #endif write(fileno(stdout), buf, len); #if 0 fwrite(buf,1,len,stdout); fflush(stdout); #endif } /********************************************************************** * LAP control **********************************************************************/ static bool exitOnDisconnect; static void lapConnected(LAP* lap) { if(verbosity>0) birda_log("LAP connected\n"); } static void lapDisconnected(LAP* lap) { if(verbosity>0) birda_log("LAP disconnected\n"); if(exitOnDisconnect) exit(0); } /********************************************************************** * Main function **********************************************************************/ static const char* description="Accept incoming OBEX and COMM connections"; static Option options[] = { { OPTION_BOOL, 'o', 0, "OBEX server saving objects to file" }, { OPTION_INT, 's', "port", "OBEX server writing objects to socket" }, { OPTION_BOOL, 'c', 0, "COMM server" }, { OPTION_BOOL, 'e', 0, "Exit on disconnect" }, { OPTION_BOOL, 'i', 0, "Initiate LAP connection" }, { OPTION_INT, 'O', "port", "Accept OBEX objects on this port and send them" } }; int main(int argc, char** argv) { doOptions(argc,argv,6,options,&verbosity,description); optLapConnected=lapConnected; optLapDisconnected=lapDisconnected; exitOnDisconnect=options[3].val.b; if(options[0].val.b) { OBEXServer* obexServ=createOBEXServer(optLap,optIas); obexServ->handle=0; obexServ->object=objectToFile; if(verbosity>0) obexServ->debug|=OBEX_DEBUG_INFO; } if(options[1].val.i) { OBEXServer* obexServ=createOBEXServer(optLap,optIas); obexServ->handle=0; obexServ->object=objectToSocket; port = options[1].val.i; if(verbosity>0) obexServ->debug|=OBEX_DEBUG_INFO; } if(options[2].val.b) { COMMServer* commServ=createCOMMServer(optLap,optIas); COMMPort* commPort=commSrvNewPort(commServ); commPort->status=commStatus; commPort->data=commData; if(verbosity>0) commServ->debug|=COMM_DEBUG_INFO; } if(options[4].val.b) doConnect(); if(options[5].val.i) { createOBEXSender(options[5].val.i); } evtLoop(); return 0; }