diff -urN ftpd-topfield-0.7.7/ChangeLog.topfield ftpd-topfield-0.7.7p/ChangeLog.topfield --- ftpd-topfield-0.7.7/ChangeLog.topfield 2008-11-07 22:23:55.000000000 +0000 +++ ftpd-topfield-0.7.7p/ChangeLog.topfield 2011-03-19 01:42:21.000000000 +0000 @@ -1,3 +1,68 @@ +2011-03-19 Gordon Lack + * Version 0.7.7p + * Makefile + Set VERSION to 0.7.7p + Define USE_LIBUSB for help in ftpd.c + * libtopfield/Makefile + Add toppdy and toppyd-test to clean list + Remove empty ifdef USE_LIBUSB/endif block + * Makefile and libtopfield/Makefile + Changed to allow specification of where libusb is, to + force its location into the RPATH (for dynamic loading) + and to allow static linking of it. + [STATIC, LIBUSBLOC, FORCELIBUSBLOC] + Removed "-LIBUSB ?= -lusb" setting, as it will be set, and + might be set to force using the static lib. + * ftpd.c: + Change usage text for -X if NEW_DEV_SCAN is defined. + * tf_fwio.c, tf_io.c, usb_io.c and usb_io.h: (libtopfield) + Changed to rename usb_bulk_read and usb_bulk_write to + MY_usb_bulk_read and MY_usb_bulk_write respectively to + avoid any symbol clashes with libusb. + * tf_io.c: (libtopfield) + Changed to add __may_alias__ as an attribute to typedef + struct of tf_typefile_t to avoid warnings with gcc4.4. + +2010-04-07 Gordon Lack + * Minor mods for MacOSX + config.h MacOSX has daemonize, so let __APPLE_ define + HAVE_DAEMON. + ftpd.c Add va_copy code to reply and lreply. + * Left version number alone. + +2009-05-25 Gordon Lack + * mods to remove all compile warnings. + libtopfield/tf_fwio.c: + array bounds on p[i] at line 359. + ftpd.c + Cast current to (long long) in printf and + use %lld, not %Ld everywhere. + * Left version number alone. + +2008-12-04 Gordon Lack + * Version 0.7.7n + Corresponding changes in puppy-1.14n. + * ftpd.c, tf_open.c, tf_open.h, toppyd.c, usb_io.h, usbutil.c, + usbutil.h + Use libusb to scan bus for devices by: + o use first found (default) + o use Nth (count from 0) + o use mmm/nnn as Bus mmm Dev nnn + o use Toppy with given serial number + Enabled -X as short option for this. + * Remove /tmp/puppy lock. Claiming USB device is exclusive. + * Build options now: + make + => New bus scan + make OLD_DEV_SCAN=1 USE_LIBUSB=1 + => Will build the old code, but use libusb to find + the device. It will create /tmp/puppy lock files. + make OLD_DEV_SCAN=1 + => This will build the old code, but read the + /proc/bus/usb/devices file to determine + devices (which is a deprecated method). + It will create lock files. + 2008-10-27 Steve Bennett * Version 0.7.7 diff -urN ftpd-topfield-0.7.7/Makefile ftpd-topfield-0.7.7p/Makefile --- ftpd-topfield-0.7.7/Makefile 2008-11-07 22:23:55.000000000 +0000 +++ ftpd-topfield-0.7.7p/Makefile 2011-03-20 18:21:32.000000000 +0000 @@ -1,12 +1,46 @@ -include config.mak -VERSION=0.7.7 +VERSION=0.7.7p LDLIBS += -Llibtopfield -ltopfield +ifeq ($(SYSTEM),Linux) + +# Enable new scan mode by default - needs libusb +# + ifndef OLD_DEV_SCAN + USE_LIBUSB = 1 + CFLAGS += -DNEW_DEV_SCAN + endif + +# Let us say where we have libusb installed - for "personal" installs + ifdef LIBUSBLOC + CFLAGS += -I$(LIBUSBLOC)/include + LFLAGS += -L$(LIBUSBLOC)/lib + endif + +# !!! These need to get added at the *END* of the compile line!!!! + ifdef STATIC + ifdef LIBUSBLOC + LDLIBS += $(LIBUSBLOC)/lib/libusb.a + else +# New gcc (gcc4?) allows this syntax for .a by dir searching + LDLIBS += -l:libusb.a + endif + else + LIBUSB := -lusb + ifdef FORCELIBUSBLOC + LFLAGS += -Wl,-rpath,$(LIBUSBLOC)/lib + endif + endif + +endif + ifdef USE_LIBUSB -LIBUSB ?= -lusb -LDLIBS += $(LIBUSB) +# LIBUSB will be defined when we get here if we are using libusb + LDLIBS += $(LIBUSB) +# USE_LIBUSB is not the same as NEW_DEV_SCAN for ftpd-topfield + CFLAGS += -DUSE_LIBUSB endif #CFLAGS += -DDEBUG #-DIGNORE_NO_TOPFIELD diff -urN ftpd-topfield-0.7.7/config.h ftpd-topfield-0.7.7p/config.h --- ftpd-topfield-0.7.7/config.h 2007-02-21 00:27:52.000000000 +0000 +++ ftpd-topfield-0.7.7p/config.h 2010-03-07 16:37:20.000000000 +0000 @@ -556,7 +556,8 @@ #endif /* Define to one if you have 'daemon' function */ -#if defined(__uClinux__) || defined(__APPLE__) +/* #if defined(__uClinux__) || defined(__APPLE__) */ +#if defined(__uClinux__) #undef HAVE_DAEMON #else #define HAVE_DAEMON 1 diff -urN ftpd-topfield-0.7.7/ftpd.c ftpd-topfield-0.7.7p/ftpd.c --- ftpd-topfield-0.7.7/ftpd.c 2008-11-07 22:23:55.000000000 +0000 +++ ftpd-topfield-0.7.7p/ftpd.c 2011-03-19 01:12:22.000000000 +0000 @@ -120,13 +120,23 @@ static tf_handle tf; static int topfield_is_open = 0; static int verbose = 0; +#ifndef NEW_DEV_SCAN static int lockfd = -1; +#endif static int got_sighup = 0; static int no_dns = 1; static int use_eplf = 0; static char *topfield_cwd = 0; + +#ifdef NEW_DEV_SCAN +#define MAX_DEVLEN 64 +static char topfield_device_buf[MAX_DEVLEN]; +static char *topfield_device = NULL; +#else static int topfield_device = 0; +#endif + static int opt_crc_check = 0; jmp_buf errcatch; @@ -188,7 +198,7 @@ static void sighup __P ((int)); static void usage __P ((const char *progname, int err)); -static const char *short_options = "Aa:bcDdeEhlp:P:qRt:T:u:vV"; +static const char *short_options = "Aa:bcDdX:eEhlp:P:qRt:T:u:vV"; static struct option long_options[] = { { "anonymous-only", no_argument, 0, 'A' }, @@ -235,7 +245,7 @@ syslog(LOG_INFO,"%s %s%s", cmd, *(file) == '/' ? "" : curdir(), file); } else { - syslog(LOG_INFO, "%s %s%s = %Ld bytes", cmd, (*(file) == '/') ? "" : curdir(), file, (long long)cnt); + syslog(LOG_INFO, "%s %s%s = %lld bytes", cmd, (*(file) == '/') ? "" : curdir(), file, (long long)cnt); } } } @@ -256,9 +266,16 @@ -b, --turbo Default to turbo mode on for transfers\n\ -c, --crc-check Enable crc check on received packets\n\ -D, --daemon Start the ftpd standalone\n\ - -d, --debug Debug mode\n\ - --device n Select topfield device (first is 0, second is 1, etc.)\n\ - -E, --eplf Send listing in EPLF mode\n\ + -d, --debug Debug mode\n" +#ifdef NEW_DEV_SCAN +" -X, --device n Select topfield device (first is 0, second 1,\n\ + etc.) or\n\ + item 00b/00d on USB bus or\n\ + USB product serial number\n" +#else +" -X, --device n Select topfield device (first is 0, second is 1, etc.)\n" +#endif +" -E, --eplf Send listing in EPLF mode\n\ -l, --logging Increase verbosity of syslog messages\n\ -p, --pidfile=[PIDFILE] Change default location of pidfile\n\ -P, --port=[port] Change the port to listen on in server mode\n\ @@ -318,7 +335,16 @@ break; case 'X': /* Select device */ +#ifdef NEW_DEV_SCAN + if (strlen(optarg) >= MAX_DEVLEN) { + fprintf(stderr, "device descriptor too long\n"); + return 1; + } + topfield_device = topfield_device_buf; + strcpy(topfield_device, optarg); +#else topfield_device = atoi(optarg); +#endif break; case 'E': /* Enable eplf listings */ @@ -538,9 +564,18 @@ syslog (LOG_DEBUG, "open_topfield(intr_transfer=%d), topfield_is_open=%d", intr_transfer, topfield_is_open); } if (!topfield_is_open) { +#ifdef NEW_DEV_SCAN + int ret = topfield_open(&tf, topfield_device); +#else int ret = topfield_open(&tf, topfield_device, TF_LOCK_HUP); +#endif if (debug) { +#ifdef NEW_DEV_SCAN + syslog (LOG_DEBUG, "topfield_open(%s) returned %d", + topfield_device? topfield_device: "default", ret); +#else syslog (LOG_DEBUG, "topfield_open(%d) returned %d", topfield_device, ret); +#endif } if (ret > 0) { /* Failed to lock either because something bad happened or @@ -559,7 +594,9 @@ tf.nocrc = opt_crc_check ? 0 : 1; if (tf_init(&tf) != 0) { +#ifndef NEW_DEV_SCAN close(lockfd); +#endif topfield_close(&tf); reply(550, "Failed to establish communication with Topfield"); return 0; @@ -578,7 +615,9 @@ if (topfield_is_open) { topfield_close(&tf); topfield_is_open = 0; +#ifndef NEW_DEV_SCAN close(lockfd); +#endif } } @@ -956,10 +995,10 @@ /* Retry a few times if necessary */ while (!aborted) { - syslog(LOG_INFO, "retrieve: %s @%Ld", srcpath, (long long)current); + syslog(LOG_INFO, "retrieve: %s @%lld", srcpath, (long long)current); if (current % 512 != 0) { - fprintf(stderr, "Note: request for data not on 512 byte boundary (%Ld %% 512 == %Ld)\n", (long long)current, (long long)(current % 512)); + fprintf(stderr, "Note: request for data not on 512 byte boundary (%lld %% 512 == %lld)\n", (long long)current, (long long)(current % 512)); skip = current % 512; current -= skip; } @@ -977,9 +1016,9 @@ ret = tf_cmd_get(&tf, srcpath, current, &dirent); if (debug) { - fprintf(stderr, "retrieve: srcpath=%s, current=%Ld, ret=%d\n", srcpath, current, ret); + fprintf(stderr, "retrieve: srcpath=%s, current=%lld, ret=%d\n", srcpath, (long long)current, ret); } - //syslog(LOG_INFO, "tf_cmd_get(%s, current=%Ld) returned ret=%d, size=%Ld", srcpath, current, ret, dirent.size); + //syslog(LOG_INFO, "tf_cmd_get(%s, current=%lld) returned ret=%d, size=%lld", srcpath, current, ret, dirent.size); if (ret != 0) { if (debug) { @@ -1026,7 +1065,7 @@ /* The topfield will return data past the end of the file. Don't let it */ if (current >= dirent.size) { if (debug) { - fprintf(stderr, "past EOF (%Ld >= %Ld)", current, dirent.size); + fprintf(stderr, "past EOF (%lld >= %lld)", (long long)current, dirent.size); } ret = 1; break; @@ -1061,7 +1100,7 @@ #if 0 /* Don't return data past the length of the file */ if (current + len > dirent.size) { - syslog(LOG_INFO, "would pass EOF, %Ld + len=%d > %Ld, so len %d -> %Ld", current, len, dirent.size, len, dirent.size - current); + syslog(LOG_INFO, "would pass EOF, %lld + len=%d > %lld, so len %d -> %lld", current, len, dirent.size, len, dirent.size - current); len = dirent.size - current; } #endif @@ -1167,7 +1206,7 @@ /* If we fell out of get and write() did not fail, we can resume */ if (!in_get && ret != -200 && ret != -426) { if (debug) { - fprintf(stderr, "Resuming paused get @%lld %s\n", current, srcpath); + fprintf(stderr, "Resuming paused get @%lld %s\n", (long long)current, srcpath); } continue; } @@ -1213,16 +1252,16 @@ /*fprintf(stderr, "Finishing up and closing data connection\n");*/ if (ret >= 0) { - syslog(LOG_INFO, "retrieve: Completed transfer of %s @%Ld", srcpath, (long long)current); + syslog(LOG_INFO, "retrieve: Completed transfer of %s @%lld", srcpath, (long long)current); reply (226, "Transfer complete."); } else if (!replied) { if ( ret == -426 ) { - syslog(LOG_INFO, "retrieve: Transfer of %s aborted @%Ld", srcpath, (long long)current); + syslog(LOG_INFO, "retrieve: Transfer of %s aborted @%lld", srcpath, (long long)current); reply (426, "Transfer aborted. Data connection closed."); } else { - syslog(LOG_INFO, "retrieve: Transfer of %s failed @%Ld", srcpath, (long long)current); + syslog(LOG_INFO, "retrieve: Transfer of %s failed @%lld", srcpath, (long long)current); perror_reply (550, name); } } @@ -1274,7 +1313,11 @@ start = time(0); +#ifdef NEW_DEV_SCAN + while (topfield_open(&tf, topfield_device) != 0) { +#else while (topfield_open(&tf, topfield_device, TF_LOCK_STD) != 0) { +#endif /* Wait up to 20 seconds to connect after reboot */ if (time(0) - start > 20) { perror_reply(550, "Failed to reconnect after reboot"); @@ -1359,7 +1402,7 @@ transflag = 1; - syslog(LOG_INFO, "store: %s %s @%Ld", turbo ? "(turbo)" : "", destpath, (long long)current); + syslog(LOG_INFO, "store: %s %s @%lld", turbo ? "(turbo)" : "", destpath, (long long)current); /* Do we need to append to an existing file? */ if (*mode == 'a') { @@ -1389,7 +1432,7 @@ resume_put: - syslog(LOG_INFO, "store: Starting at %s @%Ld", destpath, (long long)current); + syslog(LOG_INFO, "store: Starting at %s @%lld", destpath, (long long)current); ret = tf_cmd_put(&tf, destpath, 0, time(0), current); @@ -1398,7 +1441,7 @@ #endif if (ret != 0) { - syslog(LOG_INFO, "store: Failed transfer of %s @%Ld", destpath, (long long)current); + syslog(LOG_INFO, "store: Failed transfer of %s @%lld", destpath, (long long)current); perror_reply (553, name); LOGCMD (*mode == 'w' ? "put" : "append", name); @@ -1471,7 +1514,7 @@ if (ret >= 0) { /*fprintf(stderr, "put: tf_cmd_put_done()\n");*/ - syslog(LOG_INFO, "store: Completed transfer of %s @%Ld", destpath, (long long)current); + syslog(LOG_INFO, "store: Completed transfer of %s @%lld", destpath, (long long)current); ret = tf_cmd_put_done(&tf); reply (226, "Transfer complete."); } @@ -1484,7 +1527,7 @@ goto resume_put; } - syslog(LOG_INFO, "store: Failed transfer of %s @%Ld (%d)", destpath, (long long)current, ret); + syslog(LOG_INFO, "store: Failed transfer of %s @%lld (%d)", destpath, (long long)current, ret); /* Failed to cancel the put, so give up */ perror_reply (426, "Data Connection"); @@ -1494,7 +1537,7 @@ abort_buf_valid = 0; if (aborted) { tf_cmd_put_cancel(&tf); - syslog(LOG_DEBUG, "store: Aborted %s @%Ld", destpath, (long long)current); + syslog(LOG_DEBUG, "store: Aborted %s @%lld", destpath, (long long)current); } if (turbo) { @@ -1569,7 +1612,7 @@ file_size = size; byte_count = 0; if (size != (off_t) -1) - (void) snprintf(sizebuf, sizeof(sizebuf), " (%Ld bytes)", + (void) snprintf(sizebuf, sizeof(sizebuf), " (%lld bytes)", (long long)size); else *sizebuf = '\0'; @@ -1816,21 +1859,26 @@ void reply (int n, const char *fmt, ...) { - va_list ap; + va_list ap, aq; #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ va_start (ap, fmt); #else va_start (ap); #endif +#ifdef va_copy + va_copy(aq, ap); +#else + aq = ap; +#endif (void)printf ("%d ", n); - (void)vprintf (fmt, ap); + (void)vprintf (fmt, aq); (void)printf ("\r\n"); (void)fflush (stdout); if (debug) { syslog (LOG_DEBUG, "<--- %d ", n); #ifdef HAVE_VSYSLOG - vsyslog (LOG_DEBUG, fmt, ap); + vsyslog (LOG_DEBUG, fmt, aq); #endif } } @@ -1838,21 +1886,26 @@ void lreply (int n, const char *fmt, ...) { - va_list ap; + va_list ap, aq; #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ va_start (ap, fmt); #else va_start (ap); #endif +#ifdef va_copy + va_copy(aq, ap); +#else + aq = ap; +#endif (void)printf ("%d- ", n); - (void)vprintf (fmt, ap); + (void)vprintf (fmt, aq); (void)printf ("\r\n"); (void)fflush (stdout); if (debug) { syslog (LOG_DEBUG, "<--- %d- ", n); #ifdef HAVE_VSYSLOG - vsyslog (LOG_DEBUG, fmt, ap); + vsyslog (LOG_DEBUG, fmt, aq); #endif } } @@ -2034,10 +2087,10 @@ if (strcmp (cp, "STAT\r\n") == 0) { if (file_size != (off_t) -1) - reply (213, "Status: %Ld of %Ld bytes transferred", + reply (213, "Status: %lld of %lld bytes transferred", (long long)byte_count, (long long)file_size); else - reply (213, "Status: %Ld bytes transferred", + reply (213, "Status: %lld bytes transferred", (long long)byte_count); } } diff -urN ftpd-topfield-0.7.7/libtopfield/Makefile ftpd-topfield-0.7.7p/libtopfield/Makefile --- ftpd-topfield-0.7.7/libtopfield/Makefile 2008-05-08 05:36:42.000000000 +0100 +++ ftpd-topfield-0.7.7p/libtopfield/Makefile 2011-03-20 18:22:11.000000000 +0000 @@ -7,17 +7,48 @@ LFLAGS += -g LDLIBS += -L. -ltopfield -OBJS=crc16.o daemon.o mjd.o tf_bytes.o tf_io.o tf_fwio.o tf_open.o tf_util.o +ifeq ($(SYSTEM),Linux) + +# Enable new scan mode by default - needs libusb +# + ifndef OLD_DEV_SCAN + USE_LIBUSB = 1 + CFLAGS += -DNEW_DEV_SCAN + endif + +# Let us say where we have libusb installed - for "personal" installs + ifdef LIBUSBLOC + CFLAGS += -I$(LIBUSBLOC)/include + LFLAGS += -L$(LIBUSBLOC)/lib + endif + +# !!! These need to get added at the *END* of the compile line!!!! + ifdef STATIC + ifdef LIBUSBLOC + LDLIBS += $(LIBUSBLOC)/lib/libusb.a + else +# New gcc (gcc4?) allows this syntax for .a by dir searching + LDLIBS += -l:libusb.a + endif + else + LIBUSB := -lusb + ifdef FORCELIBUSBLOC + LFLAGS += -Wl,-rpath,$(LIBUSBLOC)/lib + endif + endif -ifdef USE_LIBUSB endif + +OBJS=crc16.o daemon.o mjd.o tf_bytes.o tf_io.o tf_fwio.o tf_open.o tf_util.o + ifdef USE_LIBUSB -CFLAGS += -DUSE_LIBUSB -LIBUSB ?= -lusb -LDLIBS += $(LIBUSB) -OBJS += usbutil.o +# LIBUSB will be defined when we get here if we are using libusb + LDLIBS += $(LIBUSB) +# USE_LIBUSB is not the same as NEW_DEV_SCAN for ftpd-topfield + CFLAGS += -DUSE_LIBUSB + OBJS += usbutil.o usb_io.o else -OBJS += usb_io.o usb_io_util.o + OBJS += usb_io.o usb_io_util.o endif all: libtopfield.a toppyd toppyd-test test_makename test_swab test_crc @@ -46,7 +77,7 @@ ./test_swab clean: - $(RM) *.o lib*.a test_makename test_swab test_crc core core.* tags + $(RM) *.o lib*.a toppyd toppyd-test test_makename test_swab test_crc core core.* tags install: # DO NOT DELETE diff -urN ftpd-topfield-0.7.7/libtopfield/tf_fwio.c ftpd-topfield-0.7.7p/libtopfield/tf_fwio.c --- ftpd-topfield-0.7.7/libtopfield/tf_fwio.c 2007-04-19 08:27:38.000000000 +0100 +++ ftpd-topfield-0.7.7p/libtopfield/tf_fwio.c 2011-03-18 01:53:22.000000000 +0000 @@ -176,13 +176,13 @@ if (tosend > MAX_SEND_SIZE) { tosend = MAX_SEND_SIZE; } - int ret = usb_bulk_write(tf->dev, 0x01, (void *)data, tosend, tf->timeout); + int ret = MY_usb_bulk_write(tf->dev, 0x01, (void *)data, tosend, tf->timeout); - DEBUG_LOG("usb_bulk_write(endpoint=0x01, len=%d, timeout=%dms)", tosend, tf->timeout); + DEBUG_LOG("MY_usb_bulk_write(endpoint=0x01, len=%d, timeout=%dms)", tosend, tf->timeout); #ifdef DEBUG_DUMP dump_hex_buf(stderr, (__u8 *)data, tosend); #endif - DEBUG_LOG("usb_bulk_write() returned %d", ret); + DEBUG_LOG("MY_usb_bulk_write() returned %d", ret); if (ret != tosend) { tf->error = -1; break; @@ -209,8 +209,8 @@ return tf->error; } - ret = usb_bulk_read(tf->dev, 0x82, (void *)reply, sizeof(*reply), tf->timeout); - DEBUG_LOG("usb_bulk_read(endpoint=0x82, len=%d, timeout=%dms) returned %d\n", sizeof(*reply), tf->timeout, ret); + ret = MY_usb_bulk_read(tf->dev, 0x82, (void *)reply, sizeof(*reply), tf->timeout); + DEBUG_LOG("MY_usb_bulk_read(endpoint=0x82, len=%d, timeout=%dms) returned %d\n", sizeof(*reply), tf->timeout, ret); #ifdef DEBUG_DUMP if (ret > 0) { dump_hex_buf(stderr, (__u8 *)reply, ret); @@ -219,7 +219,7 @@ if (ret < PACKET_HEAD_SIZE) { if (ret >= 0) { - DEBUG_LOG("usb_bulk_read() returned ret=%d < 8", ret); + DEBUG_LOG("MY_usb_bulk_read() returned ret=%d < 8", ret); } tf->error = -1; } @@ -227,7 +227,7 @@ __u16 len = get_u16(&reply->length); if (ret < len) { - DEBUG_LOG("usb_bulk_read() returned ret=%d < len=%d", ret, len); + DEBUG_LOG("MY_usb_bulk_read() returned ret=%d < len=%d", ret, len); tf->error = -1; } else { @@ -356,7 +356,8 @@ fprintf(fh, "(%ld) %s: cmd=%s(0x%02X), len=%d, seq=0x%02X\n", time(0), prefix, tf_command_name(packet->cmd), packet->cmd, len, packet->seq); fprintf(fh, "HEADER:"); for (i = 0; i < 8; ++i) { - fprintf(fh, " %02x", p[i]); + unsigned int pp = *p++; + fprintf(fh, " %02x", pp); } for (i = 0; i < num && i < ((len + 8 + 1 + 1) & ~1); ++i) { if ((i % 32) == 0) { diff -urN ftpd-topfield-0.7.7/libtopfield/tf_io.c ftpd-topfield-0.7.7p/libtopfield/tf_io.c --- ftpd-topfield-0.7.7/libtopfield/tf_io.c 2008-05-08 05:36:42.000000000 +0100 +++ ftpd-topfield-0.7.7p/libtopfield/tf_io.c 2011-03-18 01:53:29.000000000 +0000 @@ -78,7 +78,7 @@ __u8 name[95]; __u8 unused; __u32 attrib; -} __attribute__ ((packed)) tf_typefile_t; +} __attribute__ ((packed, __may_alias__)) tf_typefile_t; /* Topfield command codes */ #define TF_MSG_FAIL 0x0001 @@ -270,11 +270,11 @@ /* Pad with zero bytes for safety */ /*memset(((unsigned char *)req->data) + len, 0, pad);*/ } - DEBUG_LOG("usb_bulk_write(len=%d)", len); + DEBUG_LOG("MY_usb_bulk_write(len=%d)", len); #ifdef DEBUG_DUMP dump_hex_buf(tf->tracefh, (void *)req, len); #endif - int ret = usb_bulk_write(tf->dev, 0x01, (void *)req, len, tf->timeout); + int ret = MY_usb_bulk_write(tf->dev, 0x01, (void *)req, len, tf->timeout); tf->error = (ret == len) ? TF_ERR_NONE : TF_ERR_IO; } @@ -296,11 +296,11 @@ return tf->error; } - ret = usb_bulk_read(tf->dev, 0x82, (void *)reply, sizeof(*reply), tf->timeout); + ret = MY_usb_bulk_read(tf->dev, 0x82, (void *)reply, sizeof(*reply), tf->timeout); if (ret < PACKET_HEAD_SIZE) { if (ret >= 0) { - DEBUG_LOG("usb_bulk_read() returned ret=%d < 8", ret); + DEBUG_LOG("MY_usb_bulk_read() returned ret=%d < 8", ret); } tf->error = TF_ERR_IO; } @@ -308,7 +308,7 @@ __u16 len = get_u16_raw(&reply->length); if (ret < len) { - DEBUG_LOG("usb_bulk_read() returned ret=%d < len=%d", ret, len); + DEBUG_LOG("MY_usb_bulk_read() returned ret=%d < len=%d", ret, len); tf->error = TF_ERR_IO; } else { diff -urN ftpd-topfield-0.7.7/libtopfield/tf_open.c ftpd-topfield-0.7.7p/libtopfield/tf_open.c --- ftpd-topfield-0.7.7/libtopfield/tf_open.c 2007-02-21 00:27:52.000000000 +0000 +++ ftpd-topfield-0.7.7p/libtopfield/tf_open.c 2009-05-25 22:41:27.000000000 +0100 @@ -37,6 +37,10 @@ #define TOPFIELD_VENDOR_ID 0x11DB #define TOPFIELD_5000PVRT_ID 0x1000 +/* Single use is handled by usb_claim_interface + * No need for additional locking on new device scanning + */ +#ifndef NEW_DEV_SCAN /** * May return a pointer to a static buffer. */ @@ -53,12 +57,20 @@ return filename; } } +#endif +#ifdef NEW_DEV_SCAN +int topfield_open(tf_handle *tf, char *device) +#else int topfield_open(tf_handle *tf, int index, tf_lock_t lock) +#endif { memset(tf, 0, sizeof(*tf)); tf->timeout = TF_DEFAULT_TIMEOUT; tf->tracefh = stderr; +#ifdef NEW_DEV_SCAN + tf->dev = open_usb_dev(TOPFIELD_VENDOR_ID, TOPFIELD_5000PVRT_ID, device); +#else tf->lock_fd = -1; /* The lock filename MUST be compatible with puppy, otherwise @@ -128,10 +140,13 @@ } tf->dev = open_usb_dev(TOPFIELD_VENDOR_ID, TOPFIELD_5000PVRT_ID, index); +#endif if (!tf->dev) { +#ifndef NEW_DEV_SCAN close(tf->lock_fd); tf->lock_fd = -1; +#endif return -1; } @@ -148,7 +163,9 @@ tf->dev = 0; free(tf->buf); tf->buf = 0; +#ifndef NEW_DEV_SCAN close(tf->lock_fd); +#endif } } diff -urN ftpd-topfield-0.7.7/libtopfield/tf_open.h ftpd-topfield-0.7.7p/libtopfield/tf_open.h --- ftpd-topfield-0.7.7/libtopfield/tf_open.h 2007-06-04 10:09:44.000000000 +0100 +++ ftpd-topfield-0.7.7p/libtopfield/tf_open.h 2009-05-25 22:41:27.000000000 +0100 @@ -54,7 +54,9 @@ int error; /* Last error, or 0 if no error */ /* The following fields should not be touched */ +#ifndef NEW_DEV_SCAN int lock_fd; /* File used for locking to avoid Linux kernel bugs */ +#endif struct usb_dev_handle *dev; /* USB handle to the device */ int pending; /* A reply should be pending */ char *buf; /* Buffer used for transferring data during get/put */ @@ -76,8 +78,16 @@ * Pass the appropriate locking type as 'lock' * * Returns 0 if OK, 1 if already locked/in-use or < 0 on error. + * + * In NEW_DEV_SCAN mode the device string is passed in and it may be + * interpretted as the Nth device (0-based), mmm/nnn for bus/dev location + * or the USB serial id of the device. */ +#ifdef NEW_DEV_SCAN +int topfield_open(tf_handle *tf, char *device); +#else int topfield_open(tf_handle *tf, int index, tf_lock_t lock); +#endif /** * Closes a previously opened topfield device. diff -urN ftpd-topfield-0.7.7/libtopfield/toppyd.c ftpd-topfield-0.7.7p/libtopfield/toppyd.c --- ftpd-topfield-0.7.7/libtopfield/toppyd.c 2008-05-08 05:37:14.000000000 +0100 +++ ftpd-topfield-0.7.7p/libtopfield/toppyd.c 2009-05-25 22:41:27.000000000 +0100 @@ -118,7 +118,11 @@ static int open_topfield(int intr_transfer) { if (!topfield_is_open) { +#ifdef NEW_DEV_SCAN + int ret = topfield_open(&tf, NULL); +#else int ret = topfield_open(&tf, devindex, TF_LOCK_HUP); +#endif LOG("topfield_open() returned %d\n", ret); diff -urN ftpd-topfield-0.7.7/libtopfield/usb_io.c ftpd-topfield-0.7.7p/libtopfield/usb_io.c --- ftpd-topfield-0.7.7/libtopfield/usb_io.c 2007-02-21 00:27:52.000000000 +0000 +++ ftpd-topfield-0.7.7p/libtopfield/usb_io.c 2011-03-18 01:53:34.000000000 +0000 @@ -56,7 +56,7 @@ } /* This function is adapted from libusb */ -ssize_t usb_bulk_write(struct usb_dev_handle *dev, int ep, const __u8 * bytes, ssize_t length, int timeout) +ssize_t MY_usb_bulk_write(struct usb_dev_handle *dev, int ep, const __u8 * bytes, ssize_t length, int timeout) { struct usbdevfs_bulktransfer bulk; ssize_t ret; @@ -102,7 +102,7 @@ } /* This function is adapted from libusb */ -ssize_t usb_bulk_read(struct usb_dev_handle *dev, int ep, __u8 * bytes, ssize_t size, int timeout) +ssize_t MY_usb_bulk_read(struct usb_dev_handle *dev, int ep, __u8 * bytes, ssize_t size, int timeout) { struct usbdevfs_bulktransfer bulk; ssize_t ret; diff -urN ftpd-topfield-0.7.7/libtopfield/usb_io.h ftpd-topfield-0.7.7p/libtopfield/usb_io.h --- ftpd-topfield-0.7.7/libtopfield/usb_io.h 2008-05-08 05:36:42.000000000 +0100 +++ ftpd-topfield-0.7.7p/libtopfield/usb_io.h 2011-03-18 01:53:39.000000000 +0000 @@ -28,6 +28,20 @@ #ifdef USE_LIBUSB #include +#include +#include +#include +#include + +struct usb_dev_handle { + int fd; +}; + +ssize_t MY_usb_bulk_write(struct usb_dev_handle *dev, int ep, + const __u8 * bytes, ssize_t length, int timeout); +ssize_t MY_usb_bulk_read(struct usb_dev_handle *dev, int ep, + __u8 * bytes, ssize_t size, int timeout); + #else #include @@ -53,8 +67,8 @@ typedef struct usb_dev_handle usb_dev_handle; -ssize_t usb_bulk_write(struct usb_dev_handle *dev, int ep, const __u8 * bytes, ssize_t length, int timeout); -ssize_t usb_bulk_read(struct usb_dev_handle *dev, int ep, __u8 * bytes, ssize_t size, int timeout); +ssize_t MY_usb_bulk_write(struct usb_dev_handle *dev, int ep, const __u8 * bytes, ssize_t length, int timeout); +ssize_t MY_usb_bulk_read(struct usb_dev_handle *dev, int ep, __u8 * bytes, ssize_t size, int timeout); #endif diff -urN ftpd-topfield-0.7.7/libtopfield/usbutil.c ftpd-topfield-0.7.7p/libtopfield/usbutil.c --- ftpd-topfield-0.7.7/libtopfield/usbutil.c 2006-01-26 12:48:34.000000000 +0000 +++ ftpd-topfield-0.7.7p/libtopfield/usbutil.c 2009-05-25 22:41:27.000000000 +0100 @@ -30,6 +30,98 @@ #include "usbutil.h" +#ifdef NEW_DEV_SCAN +#include +#endif + +/* The method for usb_dev_handle finding *what* to open depends very much + * on the NEW_DEV_SCAN, so only the end of this function is common. + */ +#ifdef NEW_DEV_SCAN +struct usb_dev_handle *open_usb_dev(int vendor_id, int product_id, char *device) +{ + int err = 0; + int found = 0; + int count = 0; + struct usb_dev_handle *devh = NULL; + struct usb_device *usb_dev = NULL; + struct usb_bus *bus = NULL; + char serial[64]; + char bus_buf[4], dev_buf[4]; + char *want_bus, *want_dev; + int want_nth; + + want_bus = bus_buf; + want_dev = dev_buf; + + usb_init(); + usb_find_busses(); + usb_find_devices(); + +/* If device is NULL, we just get the first toppy. + * If it is a single digit, we get the (N-1)th toppy (historic). + * If it matches xxx/yyy we look for Bus xxx, Device yyy + * Otherwise we look for a Toppy with the given Serial number + */ + if (device) { + if ((strlen(device) == 1) && + (*device >= '0' && *device <= '9')) { + want_nth = *device - '0'; + want_bus = NULL; + want_dev = NULL; + } + else { + if (2 == sscanf(device, "%3s/%3s", want_bus, want_dev)) { + want_nth = -1; /* OK */ + } + else { + want_nth = -1; + want_bus = NULL; + want_dev = NULL; + } + } + } + else { + want_nth = 0; + want_bus = NULL; + want_dev = NULL; + } + +/* Loop through busses and devices to find the device with + * a matching vendor and product id + */ + + for (bus = usb_busses; bus; bus = bus->next) { + for (usb_dev = bus->devices; usb_dev; usb_dev = usb_dev->next) { + if ((usb_dev->descriptor.idVendor == vendor_id) && + (usb_dev->descriptor.idProduct == product_id)) { + if (want_nth == count++) { + found = 1; + goto got_it; + } + if (want_bus && + (0 == strcmp(want_bus, bus->dirname) && + 0 == strcmp(want_dev, usb_dev->filename))) { + found = 1; + goto got_it; + } + devh = usb_open(usb_dev); + if (devh) { + usb_get_string_simple(devh, usb_dev->descriptor.iSerialNumber, serial, sizeof(serial)); + if (0 == strcmp(serial, device)) { + found = 1; + goto got_it; + } + else { + usb_close(devh); + } + } + } + } + } +got_it: + +#else struct usb_dev_handle *open_usb_dev(int vendor_id, int product_id, int index) { int err = 0; @@ -60,6 +152,7 @@ break; } } +#endif if (!found) { return 0; diff -urN ftpd-topfield-0.7.7/libtopfield/usbutil.h ftpd-topfield-0.7.7p/libtopfield/usbutil.h --- ftpd-topfield-0.7.7/libtopfield/usbutil.h 2006-01-05 04:25:10.000000000 +0000 +++ ftpd-topfield-0.7.7p/libtopfield/usbutil.h 2011-03-18 02:16:26.000000000 +0000 @@ -32,7 +32,15 @@ * * Returns the opened device handle if OK, or 0 if error. */ + +#ifdef NEW_DEV_SCAN +#include "usb.h" + +struct usb_dev_handle *open_usb_dev(int vendor_id, int product_id, + char *device); +#else struct usb_dev_handle *open_usb_dev(int vendor_id, int product_id, int index); +#endif /** * Close a previously opened usb device.