Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ZModem communication within C Applications?

197 views
Skip to first unread message

d...@snakebrook.com

unread,
Jul 19, 2006, 11:21:50 AM7/19/06
to

Hi, I have to develop a C based application that will be able to
utilize one of the many 'sz' (ZModem send) applications to transfer
data across a modem line. I have some question on this process.

'sz' sends and receives the data (from rz) over stdin and stdout, but
I've a single file descriptior to readign and writing to the modem. So
tere seems to be a disconnect here in the way both sides are operating.
I just simply won't be able to fork or popen the 'sz' executable and
expect the file automagically appear on the other side.

What might be the best way to go about this process? Where to start?
Would there by chance be a ZModem package out there best suited for
this purpose?


Any clues appreciated.

Thanks, Dan

jasen

unread,
Jul 20, 2006, 8:44:38 AM7/20/06
to
On 2006-07-19, d...@snakebrook.com <d...@snakebrook.com> wrote:
>
>
> Hi, I have to develop a C based application that will be able to
> utilize one of the many 'sz' (ZModem send) applications to transfer
> data across a modem line. I have some question on this process.


> 'sz' sends and receives the data (from rz) over stdin and stdout, but
> I've a single file descriptior to readign and writing to the modem. So
> tere seems to be a disconnect here in the way both sides are operating.
> I just simply won't be able to fork or popen the 'sz' executable and
> expect the file automagically appear on the other side.

redirect stdout/stdin to/from the modem device.

something like this: (from memory so check each line carefully)

dup2() would seem well-suited for this


int zmodem_result=-1;

if (( childpid = fork())
{ /* child code */
dup2(modem_fd,0); // connect modem to stdin
dup2(modem_fd,1); // and stdout
execlp("rz","rz",NULL); // run rz
perror("exec() of rz failed"); // something went wrong, say what it was.
exit(-1); // give up let main task proceed.
}
else if (childpid>0)
wait( &zmodem_resiult )
else perror("fork failed");

> What might be the best way to go about this process? Where to start?
> Would there by chance be a ZModem package out there best suited for
> this purpose?

I only know of two. the Omen one and the GNU one, the GNU one seems fine,
the Omen one was good too but I lost my copy.

for more hints, you _could_ look at the source to minicom.

Bye.
Jasen

d...@snakebrook.com

unread,
Aug 3, 2006, 8:28:52 AM8/3/06
to
jasen wrote:
> On 2006-07-19, d...@snakebrook.com <d...@snakebrook.com> wrote:

[snip...]

>
> dup2() would seem well-suited for this
>
>
> int zmodem_result=-1;
>
> if (( childpid = fork())
> { /* child code */
> dup2(modem_fd,0); // connect modem to stdin
> dup2(modem_fd,1); // and stdout
> execlp("rz","rz",NULL); // run rz
> perror("exec() of rz failed"); // something went wrong, say what it was.
> exit(-1); // give up let main task proceed.
> }
> else if (childpid>0)
> wait( &zmodem_resiult )
> else perror("fork failed");
>
> > What might be the best way to go about this process? Where to start?
> > Would there by chance be a ZModem package out there best suited for
> > this purpose?
>


I have tried this, looked at the minicom source for more hints,
duplicated what minicom was doing, all to no avail. the /usr/bin/sz
program just won't shake hands with out backend ZModem software
package.

Although to test to see if they would communicate at all, I was
successful in transferring a file using minicom. So they can and will
communicate with each other, just not with the software I am writing.

if(fork() == 0)
{
dup2(fd, 0);
dup2(fd, 1);

if(execvp(args[0], args) == -1)
{
perror("execvp receive");
exit(-1);
}
}

Where 'fd' is the file descriptor I currently have open which I use to
communicate with the modem. the /usr/bin/sz program dumps the following
into the /tmp/szlog file:

Countem: 000 /tmp/RSC_09876.xml 28
countem: Total 1 28
zshhdr: f 4 ZRQINIT 80
wcsend: argc=1
wcs: name=/tmp/RSC_09876.xml
wctxpn: /tmp/RSC_09876.xml
Retry 0: Awaiting pathname nak for /tmp/RSC_09876.xml
Timeout waiting for ZRINIT
mode:0

I've also implemented some of the things monicom was doing with file
descriptiors as well but all to no avail. Obviously I am doing
something wrong, but I know not what it might be.


Any hints appreciated.


Thanks, Jack

d...@snakebrook.com

unread,
Aug 3, 2006, 8:48:58 AM8/3/06
to


PS: There must be a newsgroup better suited for questions about the
zmodem protocol. Anyone know what it is?

jasen

unread,
Aug 3, 2006, 8:34:47 PM8/3/06
to
On 2006-08-03, d...@snakebrook.com <d...@snakebrook.com> wrote:
> jasen wrote:
>> On 2006-07-19, d...@snakebrook.com <d...@snakebrook.com> wrote:
>
> [snip...]
>
> if(fork() == 0)
> {
> dup2(fd, 0);
> dup2(fd, 1);
>
> if(execvp(args[0], args) == -1)
> {
> perror("execvp receive");
> exit(-1);
> }
> }
>
> Where 'fd' is the file descriptor I currently have open which I use to
> communicate with the modem. the /usr/bin/sz program dumps the following
> into the /tmp/szlog file:
>
> Countem: 000 /tmp/RSC_09876.xml 28
> countem: Total 1 28
> zshhdr: f 4 ZRQINIT 80
> wcsend: argc=1
> wcs: name=/tmp/RSC_09876.xml
> wctxpn: /tmp/RSC_09876.xml
> Retry 0: Awaiting pathname nak for /tmp/RSC_09876.xml
> Timeout waiting for ZRINIT
> mode:0
>
> I've also implemented some of the things monicom was doing with file
> descriptiors as well but all to no avail. Obviously I am doing
> something wrong, but I know not what it might be.

There's possibly some terminal option you need to set or clear on the file
descriptor ... "man termios" for a list.

Bye.
Jasen

Josef Moellers

unread,
Aug 4, 2006, 2:45:18 AM8/4/06
to
d...@snakebrook.com wrote:

> Where 'fd' is the file descriptor I currently have open which I use to
> communicate with the modem. the /usr/bin/sz program dumps the following
> into the /tmp/szlog file:
>
> Countem: 000 /tmp/RSC_09876.xml 28
> countem: Total 1 28
> zshhdr: f 4 ZRQINIT 80
> wcsend: argc=1
> wcs: name=/tmp/RSC_09876.xml
> wctxpn: /tmp/RSC_09876.xml
> Retry 0: Awaiting pathname nak for /tmp/RSC_09876.xml
> Timeout waiting for ZRINIT
> mode:0
>
> I've also implemented some of the things monicom was doing with file
> descriptiors as well but all to no avail. Obviously I am doing
> something wrong, but I know not what it might be.

Try running rz through strace and see where it fails to work.
You can compare it with running minicom through strace.
It has helped me numerous times.

man strace

--
Josef Möllers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize
-- T. Pratchett

d...@snakebrook.com

unread,
Aug 4, 2006, 8:19:25 AM8/4/06
to
Josef Moellers wrote:
> d...@snakebrook.com wrote:

[snip...]

> Try running rz through strace and see where it fails to work.
> You can compare it with running minicom through strace.
> It has helped me numerous times.
>
> man strace


The problem here is that I am not using 'rz' on the receive end, but
rather the receive end is a Windows box running some other zmodem
software. I am running 'sz' on Linux. I can't easily debug the 'rz'
side, if at all. I havae verified thaugh that the linux 'sz' can
communicate and transfer files to the windows side though the use of
minicom. It was successful. So the problem is really in my software and
how I'm handling the file descriptiors on both ends.

My last attempt at this was to create a pipe(2) and then dup2(2) stdin
and stdout to the fd's that were reteurned from the pipe(2) call. I
then sit in a loop calling poll on pipe[0] and 'fd' waiting for
something to read. When I do detect something to read, I pass it onto
the other end. I am not sure that this is working at all, but I am not
familiar withthe zmodem protocol to know for sure. I am watching bytes
come and go from both file descriptors, and yet the 'sz' side (on the
linux box) is timing out.

Jack

d...@snakebrook.com

unread,
Aug 4, 2006, 8:45:22 AM8/4/06
to

On which fd? The fd for the modem, or stdin or stdout? I'm going to
assume the fd for the modem because I would think that something needed
to be done to the fd's that are used to read/write to the 'sz' process,
that sz would know what to do and do it.

The fd for the modem has many termios setting on it already:

newtio.c_iflag &= ~(BRKINT | ISTRIP | IUCLC | IXON | IXANY | IXOFF
| IMAXBEL);
newtio.c_iflag |= (IGNBRK | IGNPAR);
newtio.c_oflag &= ~(OLCUC);
newtio.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD);
newtio.c_cflag |= (CS8 | CREAD | HUPCL | CLOCAL);
newtio.c_cflag |= CRTSCTS;
newtio.c_lflag &= ~(ISIG | XCASE | ECHO);

tcsetattr(getmfd(), TCSANOW, &newtio);
newtio.c_iflag &=
~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
newtio.c_oflag &= ~OPOST;
newtio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
newtio.c_cflag &= ~(CSIZE|PARENB);
newtio.c_cflag |= CS8;

if(newtio.c_lflag & ECHO) printf("Yo -- ECHO is high\n");

if(tcsetattr(getmfd(), TCSANOW, &newtio) != 0)
{
perror("tcsetattr");
exit(-1);
}

jack


> Bye.
> Jasen

Josef Moellers

unread,
Aug 4, 2006, 8:49:30 AM8/4/06
to
d...@snakebrook.com wrote:
> Josef Moellers wrote:
>
>>d...@snakebrook.com wrote:
>
>
> [snip...]
>
>
>>Try running rz through strace and see where it fails to work.
>>You can compare it with running minicom through strace.
>>It has helped me numerous times.
>>
>>man strace
>
>
>
> The problem here is that I am not using 'rz' on the receive end, but
> rather the receive end is a Windows box running some other zmodem
> software. I am running 'sz' on Linux. I can't easily debug the 'rz'
> side, if at all. I havae verified thaugh that the linux 'sz' can
> communicate and transfer files to the windows side though the use of
> minicom. It was successful. So the problem is really in my software and
> how I'm handling the file descriptiors on both ends.

But then your problem lies on the linux side in sz, so s/rz/sz/ and
re-read my reply ;-)

> My last attempt at this was to create a pipe(2) and then dup2(2) stdin
> and stdout to the fd's that were reteurned from the pipe(2) call. I
> then sit in a loop calling poll on pipe[0] and 'fd' waiting for
> something to read. When I do detect something to read, I pass it onto
> the other end. I am not sure that this is working at all, but I am not
> familiar withthe zmodem protocol to know for sure. I am watching bytes
> come and go from both file descriptors, and yet the 'sz' side (on the
> linux box) is timing out.

Since you can communicate with the rz on the windows side using minicom,
then your setup of sz might be broken.

Since zmodem is a binary protocol, afaik, if you logged into a linux box
using e.g. minicom and then called "sz file", the sz would need to
change the terminal settings of it stdin and stdout and return them to
their previous state after having sent the file.

So, again, try to run sz through strace and see what it does with its
fds 0 and 1 and compare that to what minicom does with its fd(s) when it
sends a file to the windows rz.

Josef

jasen

unread,
Aug 4, 2006, 6:43:31 PM8/4/06
to
On 2006-08-04, d...@snakebrook.com <d...@snakebrook.com> wrote:
> Josef Moellers wrote:
>> d...@snakebrook.com wrote:
>
> [snip...]
>
>> Try running rz through strace and see where it fails to work.
>> You can compare it with running minicom through strace.
>> It has helped me numerous times.
>>
>> man strace
>
>
> The problem here is that I am not using 'rz' on the receive end, but
> rather the receive end is a Windows box running some other zmodem
> software. I am running 'sz' on Linux. I can't easily debug the 'rz'
> side, if at all. I havae verified thaugh that the linux 'sz' can
> communicate and transfer files to the windows side though the use of
> minicom. It was successful. So the problem is really in my software and
> how I'm handling the file descriptiors on both ends.
>
> My last attempt at this was to create a pipe(2) and then dup2(2) stdin
> and stdout to the fd's that were reteurned from the pipe(2) call.

????


> I
> then sit in a loop calling poll on pipe[0] and 'fd' waiting for
> something to read. When I do detect something to read, I pass it onto
> the other end. I am not sure that this is working at all, but I am not
> familiar withthe zmodem protocol to know for sure.

zmodem should be able to handle the serial port's file descriptors directly.
you could try dup2 ing stderr to the serial port too.

> I am watching bytes
> come and go from both file descriptors, and yet the 'sz' side (on the
> linux box) is timing out.

which means it's not getting something it was expecting... or something
it's emitting is getting mangled.

here's am idea... configure your serial connection to run at some slow rate
(eg 300 baud) and then use minicom to send a large file

400K will probably take long enough.

after the transfer has started poke around in /proc/MINICOM_PID/fd and
/prov/SZ_PID/fd and/or use lsof to get some clues on how minicom is
handing the serial connection over to sz

be aware that sz doesn't normally need a pipe or anything, it can be invoked
directly from the command line to send to a terminal program (eg: when you
are running a getty on your serial port)

Bye.
Jasen

jasen

unread,
Aug 4, 2006, 7:01:42 PM8/4/06
to
On 2006-08-04, d...@snakebrook.com <d...@snakebrook.com> wrote:
>
>> There's possibly some terminal option you need to set or clear on the file
>> descriptor ... "man termios" for a list.
>
> On which fd? The fd for the modem, or stdin or stdout? I'm going to
> assume the fd for the modem because I would think that something needed
> to be done to the fd's that are used to read/write to the 'sz' process,
> that sz would know what to do and do it.

after dup2-ing them they're all equivalent

nothing from that list jumps out at me as being wrong...
and on second thoughts sz should be capable of doing all that itself.
maybe it needs the serrial port on stderr too.

hmmm: the sz man page stinks.

--

Bye.
Jasen

0 new messages