

Show HN: Quickly copy a file between computers - diginux
https://github.com/jwilberding/bcp
Hey everyone, just wanted to share a quick project I built a bit ago and finally cleaned up enough to post.<p>The premise is simple, you have a file on one computer that you want on a different computer on the same network and don't want a lot of fuss.<p>For the file you want to copy, on the machine where the file is located, run:<p>./bcp filename<p>Now go to the computer (on the same network) where you want the file to be at, and run:<p>./bcp<p>The file will be copied over the network and you're done.<p>I created it as a nice way of not having to worry about ssh or anything else really. In fact, it is so simple, I use it on my local machine a lot when hopping around between terminals instead of remembering paths.<p>I have tested it on OSX and Linux.<p>Suggestions and comments welcomed.
======
midnightsine
$ nc -l 8888 > file

$ cat file | nc host.example.com 8888

I don't think a dedicated utility is required.

Edit: Sorry about my comment coming off as a bit hostile, I did not intend it
to be.

~~~
Udo
There are a million ways to copy files, a lot of them are simpler to use than
your example.

But that's not the point here. Sometimes you just got to make something
because you want to, because it fits a specific need that maybe not a lot of
other people have, or because it's a learning experience, or just for the heck
of it. So, no, it's not required, but that doesn't mean it's useless.

It's cool that the author did something productive that works for him/her, and
it's even cooler they shared it with everyone.

I can say that's already infinitely more than what I made today. How about
you?

~~~
azov
When the title says "Quickly copy a file..." it is reasonable to assume that
we're talking about something quicker/easier then at least the most obvious
ways to copy. But if we're talking about something you made just because you
wanted to - it is more appropriate to present it as something like "Yet
another way to copy a file..." - or, better yet, clearly state how your way is
different from a million existing ways.

~~~
larrys
Don't forget also the "yet another HN karma or attaboy builder".

(Having spent years doing minor little things that nobody ever would care to
hear about (back in the day) I can of course fully understand the positive
aspects of the mental process. You learn something and perhaps people leave
comments that make you feel good which spurs you on to do better things.)

~~~
diginux
Haha, that certainly is not the case. I made a tool, found it useful, a few of
my other friends find it useful, so I posted it.

Some people voted it up, I can't control that. I really could care less about
karma, in fact, the critical comments (except yours) have been very useful and
worth the post.

I am just being part of a community.

------
jbester
It's neat. I noticed a couple of subtle bugs.

1) The code assumes both the client and the server have the same endian. This
can be issue since a uint32 is used for both the synchronization code
(BCP_CODE) and the port. This can easily fixed with htonl/ntohl conversions.

2) it assumes both the client and the server define int to be the same size
(may or may not be true based on compiler/processor/OS combinations). If you
use stdint definitions, this typically won't be an issue.

~~~
diginux
Both great points. Will add these on my todo list. I appreciate you taking the
time to look at the code.

~~~
srl
And another, noted here: <http://news.ycombinator.com/item?id=5232416>

(Again, I don't mean to bash you or this project, just to say that it
shouldn't be used in the "real-world" without being looked at rather more
carefully. On a locally-secure network, or in an environment where security is
unimportant, it's pretty cool.)

~~~
diginux
Completely agreed, I assumed the project would give the perception that it
isn't a fully robust tool yet, but it is always worth to make it completely
clear.

------
kylecordes
Udpcast:

<http://www.udpcast.linux.lu/>

Can do this and other related useful things, including multicast of a file to
N machines in parallel. Don't let the UDP bother you: it implements
retry/checksum/etc on top of datagrams.

It's been around a few years, and is probably already in your distro.

It can pipe, as well as copy files, I wrote about it some time ago:

[http://kylecordes.com/2008/multicast-your-db-backups-with-
ud...](http://kylecordes.com/2008/multicast-your-db-backups-with-udpcast)

~~~
diginux
This is great tool and nice article. The only slightly additional requirement
for this tool is you know the name of the file being sent. I actually was
thinking of making this optional (for the same reasons they require it, to
allow many different files).

I've added a link for udpcast to my readme as an alternative. Thanks!

~~~
julian37
There's also UFTP, it doesn't require the receiver to know the file name. (But
it is different from your implementation in a number of ways, most importantly
it transfers all data via UDP.)

<http://www.tcnj.edu/~bush/uftp.html>

~~~
songgao
And it's multicast, which saves a lot of bandwidth and makes it faster :-)

------
abcd_f
Nice. Very Unix-ish in its spirit.

The client-server arrangement is backwards though :) Typical arrangement is
for the clients to do the "anyone there?" broadcast, for the servers to reply
and then the client would select the server, connect to it and they would go
about their business. In your case, the server connects to the client. If you
re-arrange this to natural client-server order, you should be able to get rid
of the fork() call and this will help with portability (not that you probably
care at this point).

Also,

    
    
      size = fread(&buf, 1, 100, ft)
    

No harm in using chunks larger than 100, especially when dispensing larger
files.

Also, consider switching to multicast for discovery.

~~~
diginux
I agree with you on it being backwards and for some reason I chose to do it
this way, though I can not now remember why.. may have just been a flawed
though, as I can see no reason not to do it your way at the moment.

Good find on the fread, that is actually a "bug", should be MAXBUFLEN instead
of 100.

Agreed on multicast, I will add that to do the todo.

Thanks for your feedback!

------
dclowd9901
I like how clever this is, but is there an option to _name_ a bcp (or a
planned option), so that I can send files among a big network with lots of
people using this command concurrently?

~~~
diginux
Yes, I plan to do this as well as have the ability for the listener to stay
active indefinitely instead of for just one transmission.

~~~
dclowd9901
Rad, especially the persistent mode.

------
froseph
It reminds me of <http://www.fefe.de/ncp/> It's always interesting when people
come up with the same thing independently.

~~~
RookToH7
I couldn't seem to get this compiled on OSX :( Do you (or anyone) know if
there's a OSX version available? What I like about ncp is that it first
requires an action at the sender (push) and then at the receiver afterwards
(poll).

------
latitude
Try and add support for detecting piped input on the server side:

    
    
      bcp < filename
    

because this would allow for things like

    
    
      cat filename | gzip | bcp
    

with the receiving end doing

    
    
      bcp | gunzip > filename
    

Keep it as simple as it is now, but make it play nicely with other tools.

~~~
lutusp
Your examples are all expected to sort out whether to accept an input stream
or start an output stream, but without an explicit command, which poses a
problem -- the app would have to determine that the input stream is empty
before switching modes to streaming output. That's not so easy -- suppose the
operator unintentionally pipes an empty input file? Will the app know what to
do?

Most (I won't say all) command-line apps must be explicitly told which mode to
use. There's a good reason.

~~~
huhtenberg
isatty() to the rescue, but that's not to say that there shouldn't be a --
option or defaulting to a different mode depending on argv[0], like gzip does.

[0]
[http://pubs.opengroup.org/onlinepubs/007904875/functions/isa...](http://pubs.opengroup.org/onlinepubs/007904875/functions/isatty.html)

------
cowmix
This reminds me of how you used to be able to disable the cypher on SSH and
now you can't. I hate that.

[http://serverfault.com/questions/116875/how-can-i-disable-
en...](http://serverfault.com/questions/116875/how-can-i-disable-encryption-
on-openssh)

~~~
ajross
Um... why? rsh still builds and works fine if that's what you want.

~~~
jbert
ssh with no cipher still requires authentication, and can stil use pubkey
auth.

So "ssh with no cipher" means "people can snoop, but I can use proper auth".
But rsh means "plaintext pw - or worse things if allowed".

------
xal
Hehe, The first thing I wrote when I learned programming ( around 1990 ) was a
tool called ipxcopy which did the same over IPX protocol that we always used
at our Lan Parties.

------
f1codz
I use (and highly recommend) _IP Messenger_ for this style of auto-discovery
of other systems on your LAN and message/file transfer:

<http://ipmsg.org/index.html.en> (For Windows)

<http://ishwt.net/en/software/ipmsg/> (For Mac)

------
jamescun
Definitely a interesting take on sharing data over a LAN but I would be
worried about the repercussions of using broadcasts to move a large quantity
of data on a larger network, cool for smaller/personal networks though.

~~~
jbester
Looking at the code, UDP/Broadcast is used only for negotiation. After
negotation, a TCP socket is used for the actual transfer.

------
dudurocha
One of the ideas I have since I was a kid, was a graphical way to copy files
between computers.

Something like you just drag for the extreme left of right border, and
sunddenly, the file is being transferred for the other computer.

~~~
diginux
If that doesn't already exist for synergy (<http://synergy-foss.org/>), that
would be an awesome addition.

~~~
readme
I think that was a planned feature for synergy. I don't think it was ever
implemented.

~~~
abcd_f
This has some usability issues, e.g. you drag a file accidentally to another
box, then change your mind and drag it back _while it is still being copied or
moved_ in the original direction. This sort of thing. It looks like a simple
and natural extension to what Synergy has, but in reality it's just a can of
worms.

~~~
diginux
I wonder if there is a way they could utilize Dropbox or Dropbox-like
functionality?

------
pyre
The example in the README could be better if the command prompt showed that
you were on different hosts. As it stands, it seems that you sent it from host
'heisenberg' to host 'heisenberg'.

~~~
dclowd9901
Different ports? Might as well be different hosts.

~~~
pyre
Actually, I didn't notice the port. I _did_ notice that the IP and hostname
were the same though.

------
dredmorbius
Reminds me of <http://www.advogato.org/article/555.html>

~~~
diginux
Great find! I added this link, as well as ncp to the README.

------
blt
python -m SimpleHTTPServer

is another nice way to do this.

~~~
diginux
I still have to know the IP of my machine, make a script wrap around python
and wget or curl to achieve the bcp functionality.

I actually use SimpleHTTPServer a lot for other things though, it is a great
tip.

------
donflamenco
Zmodem (rz/sz) works if your terminal supports it. Though putty doesn't
support it (wish it did.)

------
sebkomianos
Title should be "between computers on a lan".

------
dschiptsov
scp?)

------
huhsamovar
$ scp file host.example.com:

~~~
diginux
This assumes ssh is installed and running.

~~~
bdunbar
Your intended use is a computer that doesn't have SSH running?

~~~
diginux
I never run an ssh server on my laptops, no reason to really. Secondly, with
ssh, it requires you know ip or hostname, both which I don't want to worry
about.

~~~
bdunbar
Ah! I had not thought of copying between client computers.

Now it makes sense. And I can see it's use, at home.

Thanks.

