Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package tio for openSUSE:Factory checked in 
at 2023-09-26 22:01:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/tio (Old)
 and      /work/SRC/openSUSE:Factory/.tio.new.1770 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "tio"

Tue Sep 26 22:01:39 2023 rev:14 rq:1113517 version:2.7

Changes:
--------
--- /work/SRC/openSUSE:Factory/tio/tio.changes  2023-06-13 16:09:41.702950898 
+0200
+++ /work/SRC/openSUSE:Factory/.tio.new.1770/tio.changes        2023-09-26 
22:14:53.813081198 +0200
@@ -1,0 +2,7 @@
+Thu Sep 21 14:22:40 UTC 2023 - Martin Hauke <mar...@gmx.de>
+
+- Update to 2.7:
+  * Add xmodem and ymodem file send support
+  * fix: support --log-append in cli options
+
+-------------------------------------------------------------------

Old:
----
  tio-2.6.tar.xz

New:
----
  tio-2.7.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ tio.spec ++++++
--- /var/tmp/diff_new_pack.5eosRo/_old  2023-09-26 22:14:55.329136070 +0200
+++ /var/tmp/diff_new_pack.5eosRo/_new  2023-09-26 22:14:55.345136649 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           tio
-Version:        2.6
+Version:        2.7
 Release:        0
 Summary:        Simple TTY terminal I/O application
 License:        GPL-2.0-or-later

++++++ tio-2.6.tar.xz -> tio-2.7.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tio-2.6/AUTHORS new/tio-2.7/AUTHORS
--- old/tio-2.6/AUTHORS 2023-06-10 13:02:32.000000000 +0200
+++ new/tio-2.7/AUTHORS 2023-09-19 21:48:58.000000000 +0200
@@ -45,5 +45,8 @@
 Bill Hass <billh...@umich.edu>
 Peter van Dijk <pe...@7bits.nl>
 Braden Young <bra...@somewearlabs.com>
+Wes Koerber <wkoer...@acsd4u.com>
+HiFiPhile <ad...@hifiphile.com>
+Paul Ruizendaal <p...@planet.nl>
 
 Thanks to everyone who has contributed to this project.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tio-2.6/NEWS new/tio-2.7/NEWS
--- old/tio-2.6/NEWS    2023-06-10 13:02:32.000000000 +0200
+++ new/tio-2.7/NEWS    2023-09-19 21:48:58.000000000 +0200
@@ -1,5 +1,31 @@
 
-=== tio v2.6 ===
+=== tio v2.7 ===
+
+
+
+Changes since tio v2.6:
+
+Paul Ruizendaal:
+
+ * Add xmodem and ymodem file send support
+
+HiFiPhile:
+
+ * tty_stdin_input_thread(): write to pipe only if byte_count > 0.
+
+ * Ignore EINTR error.
+
+ * CYGWIN: Add support for "COM*" naming.
+
+Wes Koerber:
+
+ * chore: reorder log-strip and log-append
+
+   reorder to maintain consistency with documentation
+
+ * chore: update readme, bash completion, man page
+
+ * fix: support --log-append in cli options
 
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tio-2.6/README.md new/tio-2.7/README.md
--- old/tio-2.6/README.md       2023-06-10 13:02:32.000000000 +0200
+++ new/tio-2.7/README.md       2023-09-19 21:48:58.000000000 +0200
@@ -6,7 +6,7 @@
 
[![](https://img.shields.io/circleci/build/github/tio/tio)](https://circleci.com/github/tio/tio/tree/master)
 
[![](https://img.shields.io/github/v/release/tio/tio?sort=semver)](https://github.com/tio/tio/releases)
 
[![](https://img.shields.io/repology/repositories/tio)](https://repology.org/project/tio/versions)
-[![](https://img.shields.io/tokei/lines/github/tio/tio)](https://github.com/tio/tio)
+<!-- 
[![](https://img.shields.io/tokei/lines/github/tio/tio)](https://github.com/tio/tio)
 -->
 
 ## 1. Introduction
 
@@ -35,6 +35,7 @@
  * Sensible defaults (115200 8n1)
  * Support for non-standard baud rates
  * Support for RS-485 mode
+ * X-modem (1K) and Y-modem file upload
  * Support for mark and space parity
  * List available serial devices by ID
  * Show RX/TX statistics
@@ -91,6 +92,7 @@
    -L, --list-devices                     List available serial devices
    -l, --log                              Enable log to file
        --log-file <filename>              Set log filename
+       --log-append                       Append to log file
        --log-strip                        Strip control characters and escape 
sequences
    -m, --map <flags>                      Map characters
    -c, --color 0..255|bold|none|list      Colorize tio text (default: bold)
@@ -193,6 +195,8 @@
 [20:19:12.041]  ctrl-t t       Toggle line timestamp mode
 [20:19:12.041]  ctrl-t U       Toggle conversion to uppercase
 [20:19:12.041]  ctrl-t v       Show version
+[20:19:12.041]  ctrl-t x       Send file using the XMODEM protocol
+[20:19:12.041]  ctrl-t y       Send file using the YMODEM protocol
 [20:19:12.041]  ctrl-t ctrl-t  Send ctrl-t character
 ```
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tio-2.6/TODO new/tio-2.7/TODO
--- old/tio-2.6/TODO    2023-06-10 13:02:32.000000000 +0200
+++ new/tio-2.7/TODO    2023-09-19 21:48:58.000000000 +0200
@@ -1,4 +1,9 @@
- * Support for interaction using simple autoresponse strings
+* Line mode feature
+
+  Only send line when pressing enter. Maybe even add readline support so one
+  can use all the readline editing feature before sending the line.
+
+* Support for interaction using simple autoresponse strings
 
    Add support for simple autoresponse strings in the configuration file. For
    example:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tio-2.6/man/tio.1.in new/tio-2.7/man/tio.1.in
--- old/tio-2.6/man/tio.1.in    2023-06-10 13:02:32.000000000 +0200
+++ new/tio-2.7/man/tio.1.in    2023-09-19 21:48:58.000000000 +0200
@@ -309,6 +309,8 @@
 Clear screen
 .IP "\fBctrl-t L"
 Show line states (DTR, RTS, CTS, DSR, DCD, RI)
+.IP "\fBctrl-t m"
+Toggle MSB to LSB bit order
 .IP "\fBctrl-t p"
 Pulse serial port line
 .IP "\fBctrl-t q"
@@ -321,6 +323,10 @@
 Toggle conversion to uppercase on output
 .IP "\fBctrl-t v"
 Show version
+.IP "\fBctrl-t x"
+Send a file using the XMODEM protocol (prompts for file name)
+.IP "\fBctrl-t y"
+Send a file using the YMODEM protocol (prompts for file name)
 .IP "\fBctrl-t ctrl-t"
 Send ctrl-t character
 
@@ -390,6 +396,8 @@
 Enable log to file
 .IP "\fBlog-file"
 Set log filename
+.IP "\fBlog-append"
+Append to log file
 .IP "\fBlog-strip"
 Enable strip of control and escape sequences from log
 .IP "\fBlocal-echo"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tio-2.6/man/tio.1.txt new/tio-2.7/man/tio.1.txt
--- old/tio-2.6/man/tio.1.txt   2023-06-10 13:02:32.000000000 +0200
+++ new/tio-2.7/man/tio.1.txt   2023-09-19 21:48:58.000000000 +0200
@@ -305,6 +305,8 @@
 
        log-file                 Set log filename
 
+       log-append               Append to log file
+
        log-strip                Enable strip of control and escape sequences 
from log
 
        local-echo               Enable local echo
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tio-2.6/meson.build new/tio-2.7/meson.build
--- old/tio-2.6/meson.build     2023-06-10 13:02:32.000000000 +0200
+++ new/tio-2.7/meson.build     2023-09-19 21:48:58.000000000 +0200
@@ -1,12 +1,12 @@
 project('tio', 'c',
-    version : '2.6',
+    version : '2.7',
     license : [ 'GPL-2'],
     meson_version : '>= 0.53.2',
     default_options : [ 'warning_level=2', 'buildtype=release', 'c_std=gnu99' ]
 )
 
 # The tag date of the project_version(), update when the version bumps.
-version_date = '2022-12-17'
+version_date = '2023-09-19'
 
 # Test for dynamic baudrate configuration interface
 compiler = meson.get_compiler('c')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tio-2.6/src/bash-completion/tio.in 
new/tio-2.7/src/bash-completion/tio.in
--- old/tio-2.6/src/bash-completion/tio.in      2023-06-10 13:02:32.000000000 
+0200
+++ new/tio-2.7/src/bash-completion/tio.in      2023-09-19 21:48:58.000000000 
+0200
@@ -22,6 +22,7 @@
           -e --local-echo \
           -l --log \
              --log-file \
+             --log-append \
              --log-strip \
           -m --map \
           -t --timestamp \
@@ -90,6 +91,10 @@
             COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
             return 0
             ;;
+        --log-append)
+            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
+            return 0
+            ;;
         --log-strip)
             COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
             return 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tio-2.6/src/meson.build new/tio-2.7/src/meson.build
--- old/tio-2.6/src/meson.build 2023-06-10 13:02:32.000000000 +0200
+++ new/tio-2.7/src/meson.build 2023-09-19 21:48:58.000000000 +0200
@@ -17,7 +17,8 @@
   'setspeed.c',
   'rs485.c',
   'timestamp.c',
-  'alert.c'
+  'alert.c',
+  'xymodem.c'
 ]
 
 tio_dep = [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tio-2.6/src/misc.h new/tio-2.7/src/misc.h
--- old/tio-2.6/src/misc.h      2023-06-10 13:02:32.000000000 +0200
+++ new/tio-2.7/src/misc.h      2023-09-19 21:48:58.000000000 +0200
@@ -29,3 +29,6 @@
 int ctrl_key_code(unsigned char key);
 void alert_connect(void);
 void alert_disconnect(void);
+
+extern char key_hit;
+int xymodem_send(int sio, const char *filename, char mode);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tio-2.6/src/options.c new/tio-2.7/src/options.c
--- old/tio-2.6/src/options.c   2023-06-10 13:02:32.000000000 +0200
+++ new/tio-2.7/src/options.c   2023-09-19 21:48:58.000000000 +0200
@@ -46,6 +46,7 @@
     OPT_TIMESTAMP_FORMAT,
     OPT_LOG_FILE,
     OPT_LOG_STRIP,
+    OPT_LOG_APPEND,
     OPT_LINE_PULSE_DURATION,
     OPT_RESPONSE_TIMEOUT,
     OPT_RS485,
@@ -253,6 +254,7 @@
             {"list-devices",         no_argument,       0, 'L'                 
    },
             {"log",                  no_argument,       0, 'l'                 
    },
             {"log-file",             required_argument, 0, OPT_LOG_FILE        
    },
+            {"log-append",           no_argument,       0, OPT_LOG_APPEND      
    },
             {"log-strip",            no_argument,       0, OPT_LOG_STRIP       
    },
             {"socket",               required_argument, 0, 'S'                 
    },
             {"map",                  required_argument, 0, 'm'                 
    },
@@ -357,6 +359,10 @@
                 option.log_strip = true;
                 break;
 
+            case OPT_LOG_APPEND:
+                option.log_append = true;
+                break;
+
             case 'S':
                 option.socket = optarg;
                 break;
@@ -486,6 +492,19 @@
     optind = 1; // Reset option index to restart scanning of argv
     options_parse(argc, argv);
 
+#ifdef __CYGWIN__
+    unsigned char portnum;
+    char *tty_win;
+    if ( ((strncmp("COM", tty_device, 3) == 0)
+        || (strncmp("com", tty_device, 3) == 0) )
+        && (sscanf(tty_device + 3, "%hhu", &portnum) == 1)
+        && (portnum > 0) ) 
+    {
+        asprintf(&tty_win, "/dev/ttyS%hhu", portnum - 1);
+        tty_device = tty_win;
+    }
+#endif
+
     /* Restore tty device */
     option.tty_device = tty_device;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tio-2.6/src/tty.c new/tio-2.7/src/tty.c
--- old/tio-2.6/src/tty.c       2023-06-10 13:02:32.000000000 +0200
+++ new/tio-2.7/src/tty.c       2023-09-19 21:48:58.000000000 +0200
@@ -82,6 +82,8 @@
 #define CMSPAR   010000000000
 #endif
 
+#define LINE_SIZE_MAX 1000
+
 #define KEY_0 0x30
 #define KEY_1 0x31
 #define KEY_2 0x32
@@ -105,6 +107,8 @@
 #define KEY_T 0x74
 #define KEY_U 0x55
 #define KEY_V 0x76
+#define KEY_X 0x78
+#define KEY_Y 0x79
 #define KEY_Z 0x7a
 
 enum line_mode_t
@@ -133,6 +137,8 @@
 bool map_i_cr_nl = false;
 bool map_ign_cr = false;
 
+char key_hit = 0xff;
+
 static struct termios tio, tio_old, stdout_new, stdout_old, stdin_new, 
stdin_old;
 static unsigned long rx_total = 0, tx_total = 0;
 static bool connected = false;
@@ -153,6 +159,7 @@
 static pthread_t thread;
 static int pipefd[2];
 static pthread_mutex_t mutex_input_ready = PTHREAD_MUTEX_INITIALIZER;
+static char line[LINE_SIZE_MAX];
 
 static void optional_local_echo(char c)
 {
@@ -299,6 +306,11 @@
         byte_count = read(STDIN_FILENO, input_buffer, BUFSIZ);
         if (byte_count < 0)
         {
+            /* No error actually occurred */
+            if (errno == EINTR)
+            {
+                continue;
+            }
             tio_warning_printf("Could not read from stdin (%s)", 
strerror(errno));
         }
         else if (byte_count == 0)
@@ -316,6 +328,14 @@
             // Process quit and flush key command
             for (int i = 0; i<byte_count; i++)
             {
+                // first do key hit check for xmodem abort
+                if (!key_hit) {
+                    key_hit = input_buffer[i];
+                    byte_count--;
+                    memcpy(input_buffer+i, input_buffer+i+1, byte_count-i);
+                    continue;
+                }
+
                 input_char = input_buffer[i];
 
                 if (previous_char == option.prefix_code)
@@ -344,7 +364,7 @@
         }
 
         // Write all bytes read to pipe
-        while (byte_count)
+        while (byte_count > 0)
         {
             bytes_written = write(pipefd[1], input_buffer, byte_count);
             if (bytes_written < 0)
@@ -467,6 +487,33 @@
     }
 }
 
+static int tio_readln(void)
+{
+    char *p = line;
+
+    /* Read line, accept BS and DEL as rubout characters */
+    for (p = line ; p < &line[LINE_SIZE_MAX-1]; )
+    {
+        if (read(pipefd[0], p, 1) > 0)
+        {
+            if (*p == 0x08 || *p == 0x7f)
+            {
+                if (p > line )
+                {
+                    write(STDOUT_FILENO, "\b \b", 3);
+                    p--;
+                }
+                continue;
+            }
+            write(STDOUT_FILENO, p, 1);
+            if (*p == '\r') break;
+            p++;
+        }
+    }
+    *p = 0;
+    return (p - line);
+}
+
 void handle_command_sequence(char input_char, char *output_char, bool *forward)
 {
     char unused_char;
@@ -557,7 +604,9 @@
                 tio_printf(" ctrl-%c t       Toggle line timestamp mode", 
option.prefix_key);
                 tio_printf(" ctrl-%c U       Toggle conversion to uppercase on 
output", option.prefix_key);
                 tio_printf(" ctrl-%c v       Show version", option.prefix_key);
-                tio_printf(" ctrl-%c ctrl-%c  Send ctrl-%c character", 
option.prefix_key, option.prefix_key, option.prefix_key);
+                tio_printf(" ctrl-%c x       Send file via Xmodem-1K", 
option.prefix_key);
+                tio_printf(" ctrl-%c y       Send file via Ymodem", 
option.prefix_key);
+                tio_printf(" ctrl-%c ctrl-%c Send ctrl-%c character", 
option.prefix_key, option.prefix_key, option.prefix_key);
                 break;
 
             case KEY_SHIFT_L:
@@ -716,6 +765,17 @@
                 tio_printf("tio v%s", VERSION);
                 break;
 
+            case KEY_X:
+            case KEY_Y:
+                tio_printf("Send file with %cMODEM", toupper(input_char));
+                tio_printf_raw("Enter file name: ");
+                if (tio_readln()) {
+                    tio_printf("Sending file '%s'  ", line);
+                    tio_printf("Press any key to abort transfer");
+                    tio_printf("%s", xymodem_send(fd, line, input_char) < 0 ? 
"Aborted" : "Done");
+                }
+                break;
+
             case KEY_Z:
                 tio_printf_array(random_array);
                 break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tio-2.6/src/xymodem.c new/tio-2.7/src/xymodem.c
--- old/tio-2.6/src/xymodem.c   1970-01-01 01:00:00.000000000 +0100
+++ new/tio-2.7/src/xymodem.c   2023-09-19 21:48:58.000000000 +0200
@@ -0,0 +1,225 @@
+/*
+ * Minimalistic implementation of the xmodem-1k and ymodem sender protocol.
+ * https://en.wikipedia.org/wiki/XMODEM
+ * https://en.wikipedia.org/wiki/YMODEM
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later OR MIT-0
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <termios.h>
+#include "misc.h"
+
+#define STX 0x02
+#define ACK 0x06
+#define NAK 0x15
+#define CAN 0x18
+#define EOT "\004"
+
+#define OK  0
+#define ERR (-1)
+
+#define min(a, b)       ((a) < (b) ? (a) : (b))
+
+struct xpacket {
+    uint8_t  type;
+    uint8_t  seq;
+    uint8_t  nseq;
+    uint8_t  data[1024];
+    uint8_t  crc_hi;
+    uint8_t  crc_lo;
+} __attribute__((packed));
+
+/* See https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks */
+static uint16_t crc16(const uint8_t *data, uint16_t size)
+{
+    uint16_t crc, s;
+
+    for (crc = 0; size > 0; size--) {
+        s = *data++ ^ (crc >> 8);
+        s ^= (s >> 4);
+        crc = (crc << 8) ^ s ^ (s << 5) ^ (s << 12);
+    }
+    return crc;
+}
+
+static int xmodem(int sio, const void *data, size_t len, int seq)
+{
+    struct xpacket  packet;
+    const uint8_t  *buf = data;
+    char            resp = 0;
+    int             rc, crc;
+
+    /* Drain pending characters from serial line. Insist on the
+     * last drained character being 'C'.
+     */
+    while(1) {
+        if (key_hit)
+            return -1;
+        if (read(sio, &resp, 1) < 0) {
+            if (errno == EWOULDBLOCK) {
+                if (resp == 'C') break;
+                if (resp == CAN) return ERR;
+                usleep(50000);
+                continue;
+            }
+            perror("Read sync from serial failed");
+            return ERR;
+        }
+    }
+
+    /* Always work with 1K packets */
+    packet.seq  = seq;
+    packet.type = STX; 
+
+    while (len) {
+        size_t  sz, z = 0;
+        char   *from, status;
+
+        /* Build next packet, pad with 0 to full seq */
+        z = min(len, sizeof(packet.data));
+        memcpy(packet.data, buf, z);
+        memset(packet.data + z, 0, sizeof(packet.data) - z);
+        crc = crc16(packet.data, sizeof(packet.data));
+        packet.crc_hi = crc >> 8;
+        packet.crc_lo = crc;
+        packet.nseq = 0xff - packet.seq;
+
+        /* Send packet */
+        from = (char *) &packet;
+        sz =  sizeof(packet);
+        while (sz) {
+            if (key_hit)
+                return ERR;
+            if ((rc = write(sio, from, sz)) < 0 ) {
+                if (errno ==  EWOULDBLOCK) {
+                    usleep(1000);
+                    continue;
+                }
+                perror("Write packet to serial failed");
+                return ERR;
+            }
+            from += rc;
+            sz   -= rc;
+        }
+
+        /* 'lrzsz' does not ACK ymodem's fin packet */
+        if (seq == 0 && packet.data[0] == 0) resp = ACK;
+
+        /* Read receiver response, timeout 1 s */
+        for(int n=0; n < 20; n++) {
+            if (key_hit)
+                return ERR;
+            if (read(sio, &resp, 1) < 0) {
+                if (errno ==  EWOULDBLOCK) {
+                    usleep(50000);
+                    continue;
+                }
+                perror("Read ack/nak from serial failed");
+                return ERR;
+            }
+            break;
+        }
+
+        /* Update "progress bar" */
+        switch (resp) {
+        case NAK: status = 'N'; break;
+        case ACK: status = '.'; break;
+        case 'C': status = 'C'; break;
+        case CAN: status = '!'; return ERR;
+        default:  status = '?';
+        }
+        write(STDOUT_FILENO, &status, 1);
+
+        /* Move to next block after ACK */
+        if (resp == ACK) {
+            packet.seq++;
+            len -= z;
+            buf += z;
+        }
+    }
+
+    /* Send EOT at 1 Hz until ACK or CAN received */
+    while (seq) {
+        if (key_hit)
+            return ERR;
+        if (write(sio, EOT, 1) < 0) {
+            perror("Write EOT to serial failed");
+            return ERR;
+        }
+        write(STDOUT_FILENO, "|", 1);
+        usleep(1000000); /* 1 s timeout*/
+        if (read(sio, &resp, 1) < 0) {
+            if (errno == EWOULDBLOCK) continue;
+            perror("Read from serial failed");
+            return ERR;
+        }
+        if (resp == ACK || resp == CAN) {
+            write(STDOUT_FILENO, "\r\n", 2);
+            return (resp == ACK) ? OK : ERR;
+        }
+    }
+    return 0; /* not reached */
+}
+
+int xymodem_send(int sio, const char *filename, char mode)
+{
+    size_t         len;
+    int            rc, fd;
+    struct stat    stat;
+    const uint8_t *buf;
+
+    /* Open file, map into memory */
+    fd = open(filename, O_RDONLY);
+    if (fd < 0) {
+        perror("Could not open file");
+        return ERR;
+    }
+    fstat(fd, &stat);
+    len = stat.st_size;
+    buf = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
+    if (!buf) {
+        close(fd);
+        perror("Could not mmap file");
+        return ERR;
+    }
+
+    /* Do transfer */
+    key_hit = 0;
+    if (mode == 'x') {
+        rc = xmodem(sio, buf, len, 1);
+    }
+    else {
+        /* Ymodem: hdr + file + fin */
+        while(1) {
+            char hdr[1024], *p;
+
+            rc = -1;
+            if (strlen(filename) > 977) break; /* hdr block overrun */
+            p  = stpcpy(hdr, filename) + 1;
+            p += sprintf(p, "%ld %lo %o", len, stat.st_mtime, stat.st_mode);
+
+            if (xmodem(sio, hdr, p - hdr, 0) < 0) break; /* hdr with metadata 
*/
+            if (xmodem(sio, buf, len,     1) < 0) break; /* xmodem file */
+            if (xmodem(sio, "",  1,       0) < 0) break; /* empty hdr = fin */
+            rc = 0;                               break;
+        }
+    }
+    key_hit = 0xff;
+
+    /* Flush serial and release resources */
+    tcflush(sio, TCIOFLUSH);
+    munmap((void *)buf, len);
+    close(fd);
+    return rc;
+}

Reply via email to