Open with one click!
1
/* fton.c
2
* Copyright (C) 1998 N.Fukase
3
* Modified by William Stein ([email protected]), November 1999.
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330,
18
* Boston, MA 02111-1307, USA
19
*/
20
21
/*
22
** original ftr 0.1a from http://www.flatout.org/~fukase/uxrup.html
23
** mailto:[email protected] (N.Fukase)
24
** fton 0.1 (for OnHand) from http://modular.fas.harvard.edu/onhand/
25
** mailto:[email protected] (William Stein)
26
**
27
** 10-March-2002 clach04 [email protected]
28
** Increased version to 0.2
29
** Added ifdef's around readline dependent code and added quick
30
** poor-mans readline function in it's place. They may be memory leaks.
31
** Added baud rate command line option for dual Ruputer/OnHand usage.
32
** NB OnHand doesn't appear to want to do anything other than 38400!
33
** Service pack options for FileTrans have no effect.
34
** Added simple usage output.
35
** Added CTRL-C message to the connecting code.
36
** Added aliases for "bye" and "exit" - more ftp like.
37
** Added aliases for "1ls", !dir" - again more ftp like.
38
** Added "dir" which is like ls -l, but not 100% the same:
39
** does filesize,
40
** displays filename in lowercase,
41
** displays date/time (year/month/day 24 hour time)
42
** attempts to display unix like file perms, added "h" for hidden/system
43
** Added environment variables (command line params overwrde)
44
** FTON_BAUDRATE -- baud rate
45
** FTON_SERIALPORT -- serial device to use
46
**
47
** Know bugs - no params given after -l/-b - core dump do to access to argv
48
** that does not exist, the command line params could be better handled
49
** by getopt.
50
** Builds under win32 with cygwin with or without readline.
51
** Default is NOT to use readline, #define USE_READLINE if required
52
** Default serial device is /dev/ttyS0 (i.e. com1)
53
** Default baud rate is OnHand rate of 38400
54
*/
55
56
#include <stdio.h>
57
#include <string.h>
58
#include <stdlib.h>
59
#include <ctype.h>
60
#include <sys/types.h>
61
#include <sys/stat.h>
62
#include <sys/wait.h>
63
#include <fcntl.h>
64
#include <termios.h>
65
#include <unistd.h>
66
#include <time.h>
67
#include <utime.h>
68
69
#ifdef USE_READLINE
70
#include <readline/readline.h>
71
#include <readline/history.h>
72
#endif
73
74
#include "rupcommand.h"
75
#include "rupserial.h"
76
77
static char rup_line[FILENAME_MAX] = {"/dev/ttyS0"};
78
static char rup_cwd[64] = {"B:\\"};
79
static char rup_cwdA[64] = {"A:\\"};
80
static char rup_cwdB[64] = {"B:\\"};
81
static char prompt[80]= {"fton> "};
82
static char ftr_version[]= {"0.2"};
83
84
/* readline function defs */
85
#ifndef USE_READLINE
86
typedef int Function ();
87
#endif
88
89
int rlc_ls(char **coms);
90
int rlc_lsl(char **coms);
91
int rlc_ver(char **coms);
92
int rlc_ren(char **coms);
93
int rlc_cp(char **coms);
94
int rlc_mkdir(char **coms);
95
int rlc_rmdir(char **coms);
96
int rlc_del(char **coms);
97
int rlc_lpwd(char **coms);
98
int rlc_lcd(char **coms);
99
int rlc_pwd(char **coms);
100
int rlc_put(char **coms);
101
int rlc_get(char **coms);
102
int rlc_lls(char **coms);
103
int rlc_cd(char **coms);
104
int rlc_help(char **coms);
105
106
typedef enum {
107
ca_none = 0,
108
ca_remote,
109
ca_remote_d,
110
ca_local,
111
ca_local_d,
112
ca_line,
113
ca_command,
114
ca_valiable
115
} COMATTR;
116
117
typedef struct {
118
char *name;
119
COMATTR attr;
120
Function *func;
121
char *doc;
122
} COMMAND;
123
124
COMMAND commands[] = {
125
{ "bye", ca_none, NULL, "quit this programm"},
126
{ "cd", ca_remote_d, rlc_cd, "change onHand\'s current working directory"},
127
{ "close", ca_none, NULL, "close the connection to onHand"},
128
{ "cp", ca_remote_d, rlc_cp, "copy file in onHand\'s"},
129
{ "delete", ca_remote, rlc_del, "delete file in onHand"},
130
{ "dir", ca_remote, rlc_lsl, "list long contents of onHand\'s directory" },
131
{ "exit", ca_none, NULL, "quit this programm"},
132
{ "get", ca_remote, rlc_get, "get a file from onHand" },
133
{ "help", ca_command, rlc_help, "display this text" },
134
{ "?", ca_command, rlc_help, "display this text"},
135
{ "!ls", ca_local, rlc_lls, "list contents of local directory"},
136
{ "!dir", ca_local, rlc_lls, "list contents of local directory"},
137
{ "lcd", ca_local_d, rlc_lcd, "change local current working directory"},
138
{ "lls", ca_local, rlc_lls, "list contents of local directory"},
139
{ "lpwd", ca_none, rlc_lpwd, "print local current working directory" },
140
{ "ls", ca_remote, rlc_ls, "list contents of onHand\'s directory" },
141
{ "mkdir", ca_remote, rlc_mkdir, "make directory in onHand" },
142
{ "mv", ca_remote, rlc_ren, "rename file in onHand" },
143
{ "open", ca_none, NULL, "open a connection to onHand"},
144
{ "put", ca_local, rlc_put, "put a file into onHand" },
145
{ "pwd", ca_none, rlc_pwd, "print the current working directory of onHand"},
146
{ "quit", ca_none, NULL, "quit this programm"},
147
{ "exit", ca_none, NULL, "quit this programm"},
148
{ "rename", ca_remote, rlc_ren, "rename file"},
149
{ "rm", ca_remote, rlc_del, "remove file in onHand" },
150
{ "rmdir", ca_remote, rlc_rmdir, "remove a directory in onHand" },
151
{ "ver", ca_none, rlc_ver, "print WPs-DOS\'s version"},
152
{ (char *)NULL, ca_none, (Function *)NULL, (char *)NULL }
153
};
154
155
char *
156
ruputerfile_generator(char *text, int state)
157
{
158
static int list_index, len;
159
static RDENT rde = {0, NULL, ""};
160
161
if (!state) {
162
list_index = -1;
163
len = strlen(text);
164
free(rde.rfi);
165
strcpy(rde.path, rup_cwd);
166
strcat(rde.path, "*.*");
167
command_dir(&rde);
168
}
169
while ((list_index + 1) < rde.nfiles) {
170
list_index++;
171
if (strncmp(rde.rfi[list_index].name, text, len) == 0) {
172
return strdup(rde.rfi[list_index].name);
173
}
174
}
175
return ((char *)NULL);
176
}
177
178
char *
179
command_generator (char *text, int state)
180
{
181
static int list_index, len;
182
char *name;
183
184
if (!state) {
185
list_index = 0;
186
len = strlen(text);
187
}
188
while ((name = commands[list_index].name) != NULL) {
189
list_index++;
190
if (strncmp (name, text, len) == 0)
191
return strdup(name);
192
}
193
return ((char *)NULL);
194
}
195
196
#ifdef USE_READLINE
197
char **
198
rft_comp(char *text, int start, int end)
199
{
200
char **matches;
201
char buf[64];
202
int i;
203
204
matches = (char **)NULL;
205
if (start == 0)
206
matches = completion_matches(text, command_generator);
207
else {
208
strcpy(buf, rl_line_buffer);
209
if(strtok(buf, " \t") != NULL) {
210
for(i = 0; commands[i].name != NULL; i++) {
211
if (strcmp(commands[i].name, buf) == 0) {
212
if((commands[i].attr == ca_remote) || (commands[i].attr == ca_remote_d)) {
213
matches = completion_matches(text, ruputerfile_generator);
214
break;
215
} else if(commands[i].attr == ca_command) {
216
matches = completion_matches(text, command_generator);
217
break;
218
}
219
}
220
}
221
}
222
}
223
return (matches);
224
}
225
#endif
226
227
void
228
init_readline(void)
229
{
230
#ifdef USE_READLINE
231
rl_readline_name = "rft";
232
rl_attempted_completion_function = (CPPFunction *)rft_comp;
233
#endif
234
}
235
236
char *
237
myreadline(char * txt)
238
{
239
char * ret_str;
240
ret_str = malloc (sizeof(char) * 1024);
241
printf("%s", txt);
242
gets(ret_str);
243
return ret_str;
244
}
245
246
void
247
intteruct(void)
248
{
249
char *coms[256], *name, *line;
250
int i;
251
252
init_readline();
253
for(;;) {
254
#ifdef USE_READLINE
255
line = readline(prompt);
256
#else
257
line = myreadline(prompt);
258
#endif
259
if (line && *line) {
260
#ifdef USE_READLINE
261
add_history(line);
262
#endif
263
if((coms[0] = strtok(line, " \t")) == NULL) {
264
free(line);
265
continue;
266
}
267
for (i = 1; (coms[i] = strtok(NULL, " \t")) != NULL; ++i)
268
;
269
270
for (i = 0; (name = commands[i].name) != NULL; i++) {
271
if (*coms[0] == 'q' || *coms[0] == 'e' || *coms[0] == 'b') {
272
free(line);
273
return;
274
}
275
if (strcmp(name, coms[0]) == 0) {
276
if(commands[i].func != NULL)
277
(*(commands[i].func))(coms);
278
else
279
printf("Sorry! this command is not implemented yet\n");
280
break;
281
}
282
}
283
if (name == NULL)
284
printf("no such command `%s\'\n", coms[0]);
285
}
286
free(line);
287
}
288
}
289
290
/* Onhand coms routines */
291
void
292
send_file(char *fn, char *rp)
293
{
294
char *ptr;
295
int fd;
296
LENDAT dat; /* ž���ǡ�����Ǽ�� */
297
RFINFO rfi; /* ž���ǡ������� */
298
struct stat st;
299
struct tm *ftm;
300
301
if ((fd = open(fn, O_RDONLY)) >= 0) {
302
fstat(fd, &st);
303
if ((dat.data = (char *)malloc(st.st_size)) == NULL) {
304
fprintf(stderr, "Cannot allocate memory\n");
305
close(fd);
306
} else {
307
read(fd, dat.data, st.st_size);
308
dat.length = st.st_size;
309
ftm = localtime(&(st.st_mtime));
310
rfi.cdate = ((((ftm->tm_year - 80) & 0x7f) << 9) | \
311
(((ftm->tm_mon & 0xf) + 1) << 5) | \
312
(ftm->tm_mday & 0x1f));
313
rfi.ctime = (((ftm->tm_hour & 0x1f) << 11) | \
314
((ftm->tm_min & 0x3f) << 5) | \
315
((ftm->tm_sec >> 1) & 0x1f));
316
rfi.attr = 0;
317
rfi.size = st.st_size;
318
close(fd);
319
if((ptr = strrchr(fn, '/')) == NULL) {
320
strcpy(rfi.name, fn);
321
}else {
322
strcpy(rfi.name, ptr + 1);
323
}
324
command_upload(&dat, &rfi, rp);
325
free(dat.data);
326
}
327
} else
328
fprintf(stderr, "Cannot open file %s\n", fn);
329
}
330
331
void
332
recv_file(char *fn, char *rp)
333
{
334
int fd;
335
LENDAT dat; /* ž���ǡ�����Ǽ�� */
336
RFINFO rfi; /* ž���ǡ������� */
337
struct tm ftm;
338
struct utimbuf ut;
339
340
if ((fd = open(fn, O_RDWR | O_CREAT | O_EXCL, 0777)) >= 0) {
341
strncpy(rfi.name, fn, 12);
342
rfi.name[13] = '\0';
343
if (command_download(&dat, &rfi, rp) != 0) {
344
close(fd);
345
return;
346
}
347
write(fd, dat.data, dat.length);
348
close(fd);
349
ftm.tm_year = ((rfi.cdate >> 9) & 0x7f) + 80;
350
ftm.tm_mon = ((rfi.cdate >> 5) & 0xf) - 1;
351
ftm.tm_mday = (rfi.cdate & 0x1f);
352
ftm.tm_hour = ((rfi.ctime >> 11) & 0x1f);
353
ftm.tm_min = ((rfi.ctime >> 5) & 0x3f);
354
ftm.tm_sec = ((rfi.ctime & 0x1f) << 1);
355
ftm.tm_isdst = 0;
356
ut.actime = mktime(&ftm);
357
ut.modtime = ut.actime;
358
utime(rfi.name, &ut);
359
free(dat.data);
360
} else
361
fprintf(stderr, "Already have file %s\n", fn);
362
}
363
/*_____ ls _________________________________________________________________*/
364
void
365
get_file_list(char *rf, char *rp)
366
{
367
RDENT rde;
368
int i;
369
370
strcpy(rde.path, rp);
371
if (rf == NULL)
372
strcat(rde.path, "*.*");
373
else
374
strcat(rde.path, rf);
375
command_dir(&rde);
376
377
for(i = 0; i < rde.nfiles; ++i) {
378
printf("%s\n", rde.rfi[i].name);
379
}
380
free(rde.rfi);
381
}
382
383
char *
384
decode_filedate(unsigned short ohdate)
385
{
386
static char outstr[20];
387
int day, month, year;
388
389
day = ohdate & 0x1f;
390
month = ((ohdate >> 5) & 0xf); /* real month num, e.g. 1 = jan */
391
year = ((ohdate >> 9) & 0x7f) + 1980;
392
393
sprintf(outstr, "%d/%2.2d/%2.2d", year, month, day);
394
return outstr;
395
}
396
397
char *
398
decode_filetime(unsigned short ohdate)
399
{
400
static char outstr[20];
401
int sec, min, hour;
402
403
sec = (ohdate & 0x1f) * 2;
404
min = ((ohdate >> 5) & 0x3f);
405
hour = ((ohdate >> 11) & 0x1f);
406
407
sprintf(outstr, "%2.2d:%2.2d:%2.2d", hour, min, sec);
408
return outstr;
409
}
410
411
412
413
char *
414
decode_fileattr(unsigned char inatt)
415
{
416
static char outstr[12];
417
418
strcpy (outstr, "-rwxrwxrwx ");
419
/* directory */
420
if (inatt & 0x10) outstr[0] = 'd'; /* directory */
421
422
/* file */
423
if (inatt & 0x20) outstr[0] = '-'; /* file */
424
425
/* hidden */
426
if (inatt & 0x02) outstr[10] = 'h'; /* hidden */
427
return outstr;
428
}
429
430
char *
431
filename_case(char * inname)
432
{
433
static char outname[FILENAME_MAX];
434
int count = 0;
435
436
while (inname[count] != '\0' )
437
{
438
outname[count] = tolower(inname[count]);
439
count++;
440
}
441
442
outname[count] ='\0';
443
return outname;
444
}
445
446
void
447
get_file_listlong(char *rf, char *rp)
448
{
449
RDENT rde;
450
int i;
451
452
strcpy(rde.path, rp);
453
if (rf == NULL)
454
strcat(rde.path, "*.*");
455
else
456
strcat(rde.path, rf);
457
command_dir(&rde);
458
459
for(i = 0; i < rde.nfiles; ++i) {
460
printf("%s - %s %s %10.0d %s\n",
461
decode_fileattr(rde.rfi[i].attr),
462
decode_filedate(rde.rfi[i].cdate), decode_filetime(rde.rfi[i].ctime),
463
rde.rfi[i].size, filename_case(rde.rfi[i].name));
464
465
/*
466
printf("%#2.2x %d %s\n", rde.rfi[i].attr, rde.rfi[i].size, rde.rfi[i].name);
467
*/
468
}
469
free(rde.rfi);
470
}
471
472
473
void usage_message(char * cmd_name)
474
{
475
/* clach04 - follow convertions for version output */
476
fprintf(stderr, "\n%s version %s Usage:\n", cmd_name, ftr_version);
477
fprintf(stderr, "\n %s ", cmd_name);
478
/* list options */
479
fprintf(stderr, "[-v] ");
480
fprintf(stderr, "[-V] ");
481
fprintf(stderr, "[-l device] ");
482
fprintf(stderr, "[-b baudrate] ");
483
fprintf(stderr, "[non interactive commands]\n\n");
484
485
/* list explanations*/
486
fprintf(stderr, "Where:\n");
487
fprintf(stderr, " -v/-V - small version info / big info\n");
488
fprintf(stderr, " -l - specifies the device, e.g. -l /dev/ttyS0\
489
(first com port)\n");
490
fprintf(stderr, " -b - specifies the baud rate\n");
491
fprintf(stderr, " valid rates are: 19200, 38400 (default), 57600\n");
492
fprintf(stderr, " commands - list of commands to then then quit\n");
493
fprintf(stderr, " e.g. %s put test.exf\n\n", cmd_name);
494
fprintf(stderr, "Default is to open COM1 (/dev/ttyS0) with OnHand baud rate (38400)\n\n");
495
}
496
497
int
498
main(int argc, char *argv[])
499
{
500
char *name;
501
int i, c = 1, opts = 1;
502
int rn; /* ruputer negotiate */
503
char connect_speed[20] = {"38400"};
504
int show_usage = 0;
505
char *tmp_envvar;
506
507
tmp_envvar = getenv("FTON_SERIALPORT");
508
if (tmp_envvar != NULL ) strcpy (rup_line,tmp_envvar);
509
tmp_envvar = getenv("FTON_BAUDRATE");
510
if (tmp_envvar != NULL ) strcpy (connect_speed,tmp_envvar);
511
512
513
514
for (i = 1; i < argc; i++) {
515
name = argv[i];
516
if (*name == '-') {
517
opts++;
518
for (name++; *name != '\0'; name++) {
519
argv[i] = NULL;
520
if (c == i )
521
c++;
522
switch(*name) {
523
case 'V':
524
fprintf(stderr, "%s version %s\n", argv[0], ftr_version);
525
fprintf(stderr, "Copyright (C) 1998 N.Fukase\n");
526
fprintf(stderr, "All Rigth Reserverd\n");
527
return 0;
528
case 'v':
529
fprintf(stderr, "%s version %s\n", argv[0], ftr_version);
530
return 0;
531
case 'l':
532
if (name[1] == '\0') {
533
opts++;
534
i++;
535
strcpy(rup_line, argv[i]);
536
argv[i] = NULL;
537
if (c == i)
538
c++;
539
goto exit_loop;
540
} else {
541
strcpy(rup_line, name);
542
goto exit_loop;
543
}
544
break;
545
case 'b':
546
if (name[1] == '\0') {
547
opts++;
548
i++;
549
strcpy(connect_speed, argv[i]);
550
argv[i] = NULL;
551
if (c == i)
552
c++;
553
goto exit_loop;
554
} else {
555
strcpy(rup_line, name);
556
goto exit_loop;
557
}
558
break;
559
default:
560
fprintf(stderr, "Invalid option letter %c\n", *name);
561
show_usage = 1;
562
break;
563
}
564
565
}
566
exit_loop:
567
}
568
}
569
570
if (show_usage != 0 ) usage_message(argv[0]);
571
572
if (argc == opts) {
573
fprintf(stderr, "Connecting onHand on %s....\n", rup_line);
574
fprintf(stderr, "Trying to initialize line at %s baud...\n", connect_speed);
575
576
/* Open Serial port */
577
init_line(rup_line, connect_speed);
578
579
fprintf(stderr, "Line initialized. (CTRL-C to abort)\n");
580
581
/* Connect */
582
while((rn = ruputer_negotiate()) < 0)
583
fprintf(stderr, "Failure: ruputer_negotiate = %d\n", rn);
584
fprintf(stderr, "Connect!\n");
585
586
/* Ensure we are in the root drectiry of the flash drive */
587
command_chdir("b:\\");
588
589
/* Get/Run commands loop until quit */
590
intteruct();
591
592
/* Disconnect */
593
command_end();
594
/* Close Serial */
595
restore_line();
596
597
return 0;
598
} else {
599
for (i = 0; (name = commands[i].name) != NULL; i++) {
600
if ((strcmp(name, argv[c]) == 0) && (commands[i].func != NULL)){
601
init_line(rup_line, connect_speed);
602
while(ruputer_negotiate() < 0)
603
;
604
command_chdir("b:\\");
605
(*(commands[i].func))(&argv[c]);
606
command_end();
607
restore_line();
608
return 0;
609
}
610
}
611
return -1;
612
}
613
}
614
615
/* Remote ls (i.e. ls of Ruputer directory */
616
int rlc_ls(char **coms)
617
{
618
if(coms[1] == NULL)
619
get_file_list("*.*", rup_cwd);
620
else
621
get_file_list(coms[1], rup_cwd);
622
return 0;
623
}
624
625
/* Remote ls -l (i.e. ls -l of Ruputer directory */
626
int rlc_lsl(char **coms)
627
{
628
if(coms[1] == NULL)
629
get_file_listlong("*.*", rup_cwd);
630
else
631
get_file_listlong(coms[1], rup_cwd);
632
return 0;
633
}
634
635
636
637
638
/*_____ ver Ruputer��OS�С�������ɽ�� _____________________________________*/
639
int rlc_ver(char **coms)
640
{
641
int r;
642
643
r = command_ver();
644
printf("%d.%d\n", (r & 0xff), ((r & 0xff00) >> 8));
645
return 0;
646
}
647
/*_____ pwd Ruputer��CWD��ɽ�� ______________________________________________*/
648
int rlc_pwd(char **coms)
649
{
650
printf("onHand\'s Current Directory is %s\n", rup_cwd);
651
return 0;
652
}
653
/*_____ ren Ruputer��Υե�������͡��� ___________________________________*/
654
int rlc_ren(char **coms)
655
{
656
if ((coms[1] != NULL ) & (coms[2] != NULL)) {
657
command_ren(coms[2], coms[1]);
658
return 0;
659
} else {
660
printf("Too few arguement\n");
661
return -1;
662
}
663
}
664
/*_____ pwd Ruputer��Υե�����򥳥ԡ� _____________________________________*/
665
int rlc_cp(char **coms)
666
{
667
if ((coms[1] != NULL ) & (coms[2] != NULL)) {
668
command_copy(coms[2], coms[1]);
669
return 0;
670
} else {
671
printf("Too few arguement\n");
672
return -1;
673
}
674
}
675
/*_____ mkdir Ruputer��˥ǥ��쥯�ȥ���� ___________________________________*/
676
int rlc_mkdir(char **coms)
677
{
678
int i;
679
680
if (coms[1] != NULL) {
681
for (i = 1; coms[i] != NULL ; ++i) {
682
command_mkdir(coms[i]);
683
}
684
return 0;
685
} else {
686
printf("Too few arguement\n");
687
return -1;
688
}
689
}
690
/*_____ rmdir Ruputer��Υǥ��쥯�ȥ��� ___________________________________*/
691
int rlc_rmdir(char **coms)
692
{
693
int i;
694
695
if (coms[1] != NULL) {
696
for (i = 1; coms[i] != NULL ; ++i) {
697
command_rmdir(coms[i]);
698
}
699
return 0;
700
} else {
701
printf("Too few arguement\n");
702
return -1;
703
}
704
}
705
/*_____ del Ruputer��Υե������� _________________________________________*/
706
int rlc_del(char **coms)
707
{
708
int i;
709
710
if (coms[1] != NULL) {
711
for (i = 1; coms[i] != NULL ; ++i) {
712
command_del(coms[i]);
713
}
714
return 0;
715
} else {
716
printf("Too few arguement\n");
717
return -1;
718
}
719
}
720
/*_____ lpwd ��������CWDɽ��(ls�ؤ�wrapper) _________________________________*/
721
int rlc_lpwd(char **coms)
722
{
723
char buf[FILENAME_MAX];
724
725
getcwd(buf, FILENAME_MAX);
726
printf("Local current directory is %s\n", buf);
727
return 0;
728
}
729
/*_____ lcd ��������CWD��ư _________________________________________________*/
730
int rlc_lcd(char **coms)
731
{
732
char buf[FILENAME_MAX];
733
734
if (coms[1] != NULL)
735
chdir(coms[1]);
736
else
737
chdir(getenv("HOME"));
738
getcwd(buf, FILENAME_MAX);
739
printf("Now, local current directory is %s\n", buf);
740
return 0;
741
}
742
/*_____ put Ruputer�إե�����ž�� ___________________________________________*/
743
int rlc_put(char **coms)
744
{
745
if (coms[1] != NULL)
746
send_file(coms[1], rup_cwd);
747
return 0;
748
}
749
/*_____ get Ruputer����ե������ž�� _______________________________________*/
750
int rlc_get(char **coms)
751
{
752
if (coms[1] != NULL)
753
recv_file(coms[1], rup_cwd);
754
return 0;
755
}
756
757
/* Local ls */
758
int rlc_lls(char **coms)
759
{
760
int pid, status;
761
762
if ((pid = fork()) < 0) {
763
perror("fork");
764
return -1;
765
}
766
if (pid == 0) {
767
strcpy(coms[0], "ls");
768
execvp(coms[0], coms);
769
perror(coms[0]);
770
exit(-1);
771
}
772
while(wait(&status) != pid)
773
;
774
return status;
775
}
776
/*_____ cd Ruputer��CWD���ѹ� _______________________________________________*/
777
int rlc_cd(char **coms)
778
{
779
char *frm, *to, *rc, *sl, *nsl, *drv;
780
RDENT rde;
781
782
rc = NULL; sl = NULL; // to stop the warnings.
783
frm = coms[1];
784
to = rde.path;
785
786
if (frm == NULL)
787
return rlc_pwd(coms);
788
if (frm[1] == ':') {
789
if ((frm[0] == 'A') || (frm[0] == 'a')) {
790
rc = drv = rup_cwdA;
791
} else if((frm[0] == 'B') || (frm[0] == 'b')) {
792
rc = drv = rup_cwdB;
793
} else {
794
printf("Invalid drive letter\n");
795
return -1;
796
}
797
frm += 2;
798
} else {
799
if (*rup_cwd == 'A') {
800
rc = drv = rup_cwdA;
801
} else if(*rup_cwd == 'B') {
802
rc = drv = rup_cwdB;
803
}
804
strncpy(to, rc, 2);
805
}
806
strncpy(to, rc, 2);
807
to += 2;
808
rc += 2;
809
nsl = NULL;
810
if ((*frm != '\\') && (*frm != '/')) {
811
/* ���Хѥ� */
812
while((*to = *rc) != '\0') {
813
if ((*to == '\\') || (*to == '/')) {
814
*to = '\\';
815
if(nsl == NULL)
816
nsl = sl = to;
817
else {
818
sl = nsl;
819
nsl = to;
820
}
821
}
822
to++;
823
rc++;
824
}
825
if (to[-1] != '\\') {
826
*to = '\\';
827
if(nsl == NULL)
828
nsl = sl = to;
829
else {
830
sl = nsl;
831
nsl = to;
832
}
833
to++;
834
}
835
} else {
836
*to = '\\';
837
nsl = sl = to;
838
frm++;
839
to++;
840
}
841
while(*frm != '\0') {
842
if ((*frm == '.') && (frm[1] == '.')){
843
frm++;
844
if (to[-1] != '\\')
845
to = nsl;
846
else {
847
to = sl;
848
*to = '\0';
849
nsl = sl;
850
sl = strrchr(rde.path, '\\');
851
*to = '\\';
852
to++;
853
if (sl == NULL)
854
sl = nsl;
855
}
856
} else {
857
if ((*frm == '/') || (*frm == '\\')) {
858
if (to[-1] == '\\') {
859
frm++;
860
continue;
861
}
862
*to = '\\';
863
if(nsl == NULL)
864
nsl = sl = to;
865
else {
866
sl = nsl;
867
nsl = to;
868
}
869
sl = to;
870
}else
871
*to = *frm;
872
to++;
873
}
874
frm++;
875
}
876
*to = '\0';
877
if((strcmp(rde.path, "A:\\") == 0) || (strcmp(rde.path, "B:\\") == 0)) {
878
printf("Now, onHand\'s current directory is %s\n", rde.path);
879
strcpy(rup_cwd, rde.path);
880
strcat(rup_cwd, "\\");
881
if (*rup_cwd == 'A')
882
strcpy(rup_cwdA, rde.path);
883
else if (*rup_cwd == 'B')
884
strcpy(rup_cwdB, rde.path);
885
} else {
886
command_dir(&rde);
887
if(rde.nfiles == 1) {
888
printf("Now, onHand\'s current directory is %s\n", rde.path);
889
strcpy(rup_cwd, rde.path);
890
strcat(rup_cwd, "\\");
891
if (*rup_cwd == 'A')
892
strcpy(rup_cwdA, rde.path);
893
else if (*rup_cwd == 'B')
894
strcpy(rup_cwdB, rde.path);
895
}
896
}
897
return 0;
898
}
899
/*_____ ����饤��إ�פ�ɽ�� ______________________________________________*/
900
int
901
rlc_help(char **coms)
902
{
903
int i;
904
905
if(coms[1] != NULL) {
906
for(i = 0; commands[i].name != NULL; i++) {
907
if (strcmp(commands[i].name, coms[1]) == 0) {
908
printf("%s\t%s\n", commands[i].name, commands[i].doc);
909
return 0;
910
}
911
}
912
}
913
for (i = 0; commands[i].name != NULL; ++i) {
914
printf("%s\t%s\n", commands[i].name, commands[i].doc);
915
}
916
return 0;
917
}
918