-
Notifications
You must be signed in to change notification settings - Fork 1
/
cp.s
2978 lines (2606 loc) · 64.3 KB
/
cp.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
* cp - copy file
*
* Itagaki Fumihiko 05-Jul-92 Create.
* 1.0
* Itagaki Fumihiko 06-Nov-92 strip_excessive_slashes のバグfixに伴う改版.
* fatchkバグ対策.
* 些細なメッセージ変更.
* 1.2
* Itagaki Fumihiko 27-Dec-92 -I オプションと -m オプションの追加.
* Itagaki Fumihiko 28-Dec-92 プロテクトされたメディアから cp -rp でディレクトリをコピー
* できなかった不具合を修正.
* Itagaki Fumihiko 28-Dec-92 -x が正しく働いていなかったバグを修正.
* 1.3
* Itagaki Fumihiko 10-Jan-93 GETPDB -> lea $10(a0),a0
* Itagaki Fumihiko 20-Jan-93 引数 - と -- の扱いの変更
* Itagaki Fumihiko 22-Jan-93 スタックを拡張
* Itagaki Fumihiko 24-Jan-93 FATCHK のエラー EBADPARAM を無視することを忘れていたのを修正;
* -x が正しく働かない可能性があった.
* 1.4
* Itagaki Fumihiko 12-Feb-93 特殊デバイスに対応し,source と destination のどちらかで FATCHK
* が EBADPARAM 以外のエラーを返した場合には identical ではないと見
* なすようにした.
* Itagaki Fumihiko 13-Feb-93 -P foo bar で bar/foo ではなく bar/oo が作成されてしまうバグを修
* 正.
* Itagaki Fumihiko 16-Feb-93 ディレクトリを新規コピーするとき,コピー元が「属性を持たないディ
* レクトリ」である場合にもコピー先に対して -m オプションが効くよう
* 修正.
* Itagaki Fumihiko 16-Feb-93 -V オプションの追加
* Itagaki Fumihiko 16-Feb-93 その他些細な修正と最適化
* 1.5
* Itagaki Fumihiko 18-Feb-93 source が symbolic link であると exceptional abort するバグ
* (v1.5 でのエンバグ)を修正
* Itagaki Fumihiko 20-Feb-93 確認メッセージを若干詳しくした
* Itagaki Fumihiko 20-Feb-93 ボリューム・ラベルのコピー先のディレクトリ内にボリューム・ラベ
* ルが存在している場合,-f オプションが指定されていれば,それを
* 予め強制的に削除してからコピーし,そうでなければエラーとなるよ
* うにした.
* Itagaki Fumihiko 20-Feb-93 cp -r foo foo/bar (foo/bar は新規)のようなケースで無限再帰し
* ないようにした.ただし cp -r foo foo/bar/baz のようなケースで
* は,やはり無限再帰する.
* Itagaki Fumihiko 20-Feb-93 その他些細だが重要な修正
* 1.6
* Itagaki Fumihiko 18-Feb-93 source が symbolic link であるとコピーできないことがあるバグ
* (v1.5 でのエンバグ)を修正
* 1.7
* Itagaki Fumihiko 03-Nov-93 高速化
* Itagaki Fumihiko 03-Nov-93 -m-w+x (-m と mode をくっつけて指定)を許す
* Itagaki Fumihiko 03-Nov-93 -m 644 (8進数値表現)を許す
* Itagaki Fumihiko 03-Nov-93 -g オプションの追加
* 1.8(非公開)
* Itagaki Fumihiko 04-Nov-93 -g オプションを廃止.その代わり,コピー元ファイルとコピー先ファイ
* ルが同一でないことが理屈の上で明確である場合に限りチェックしない
* ようにした.
* 1.9(非公開)
* Itagaki Fumihiko 11-Nov-93 ディレクトリをコピーするとき,ディレクトリ内のシンボリック・リン
* クが正しく処理されないバグ(v1.9 でのエンバグ)を修正
* Itagaki Fumihiko 13-Nov-93 -CDLSU オプションの追加
* 2.0(非公開)
* Itagaki Fumihiko 24-Nov-93 ボリューム・ラベルをコピーするとエラーになるバグ(v1.8 でのエンバ
* グ)を修正
* 2.1(非公開)
* Itagaki Fumihiko 26-Nov-93 -Sオプションを指定すると,システム・ファイルに出会う度にファイ
* ル・ハンドルを消費してしまうバグを修正.
* Itagaki Fumihiko 26-Nov-93 再帰コピー先がデバイスであるとき(エラー),コピー先のファイル・
* ハンドルを 2度closeしてしまうバグ(実害はない)を修正.
* Itagaki Fumihiko 27-Nov-93 -pオプションを指定してもディレクトリやボリューム・ラベルのタイム
* スタンプがコピーされないバグ(v1.8 でのエンバグ)を修正.
* Itagaki Fumihiko 27-Nov-93 最適化と高速化.
* 2.2(非公開)
* Itagaki Fumihiko 02-Dec-93 -Cオプションか-Dオプションを指定すると ?: や ?:/ がコピーされない
* バグを修正.
* 2.3(非公開)
* Itagaki Fumihiko 12-Dec-93 -Cオプションを指定していているとき,調整できない名前のファイルが
* あればエラーとなるようにした.
* Itagaki Fumihiko 28-Dec-93 -Cオプションは -Bオプションに変更し,新たに -Cオプションを追加
* 2.4(非公開)
* Itagaki Fumihiko 20-Mar-94 不要コードを削除
* Itagaki Fumihiko 01-Apr-94 cp -r B:/ C:. のようなケースで, B:/foo のコピー先が C:.//foo と
* なる('/'が重複する)バグを修正.
* Itagaki Fumihiko 03-Apr-94 modeの無いファイル(おそらくデバイス)をはねるのをやめた.
* 2.5(非公開)
* Itagaki Fumihiko 08-May-94 ディレクトリの再帰の深さのチェックは, -xのチェック後にする.
* Itagaki Fumihiko 08-May-94 -Rオプションの意味を変更.
* Itagaki Fumihiko 08-May-94 -nオプションを指定しても-iオプションなどの確認は行われるようにし
* た.
* Itagaki Fumihiko 08-May-94 -Vn でもターゲットのボリュームラベルが削除されてしまうバグを修正.
* Itagaki Fumihiko 08-May-94 -Bオプション, -Cオプションによる切り詰めの方法を変更した.
* 2.6
* Itagaki Fumihiko 01-Oct-94 オープンしていないファイルをクローズする場合があるバグ(実害はほ
* とんど発生しない)を修正.
* Itagaki Fumihiko 02-Oct-94 2044年以降のファイルを-uオプションつきでコピーまたは-pオプション
* つきで上書きコピーできないバグを修正.
* Itagaki Fumihiko 02-Oct-94 -T オプションを追加.
* 2.7(非公開)
* Itagaki Fumihiko 08-Oct-94 -h オプションを追加.
* Itagaki Fumihiko 08-Oct-94 -T オプションが効く条件を変更.
* 2.8
*
* Usage: cp [ -IRSTVadfhinpsuv ] [ -m mode ] [ -- ] <ファイル1> <ファイル2>
* cp -Rr [ -BCDILUSTVadefinpsuv ] [ -m mode ] [ -- ] <ディレクトリ1> <ディレクトリ2>
* cp [ -BCDILPRSTUVadefhinprsuv ] [ -m mode ] [ -- ] <ファイル> ... <ディレクトリ>
.include doscall.h
.include error.h
.include limits.h
.include stat.h
.include chrcode.h
.xref DecodeHUPAIR
.xref getlnenv
.xref issjis
.xref islower
.xref toupper
.xref strlen
.xref strchr
.xref strcpy
.xref stpcpy
.xref strfor1
.xref strmove
.xref memmovi
.xref memmovd
.xref headtail
.xref cat_pathname
.xref skip_root
.xref find_slashes
.xref strip_excessive_slashes
REQUIRED_OSVER equ $200 * 2.00以降
MAXRECURSE equ 64 * サブディレクトリを削除するために再帰する回数の上限.
* MAXDIR (パス名のディレクトリ部 "/1/2/3/../" の長さ)
* が 64 であるから、31で充分であるが,
* シンボリック・リンクを考慮して 64 とする.
* スタック量にかかわる.
GETSLEN equ 32
FLAG_d equ 0
FLAG_e equ 1
FLAG_f equ 2
FLAG_i equ 3
FLAG_I equ 4
FLAG_n equ 5
FLAG_p equ 6
FLAG_r equ 7
FLAG_R equ 8
FLAG_s equ 9
FLAG_u equ 10
FLAG_v equ 11
FLAG_x equ 12
FLAG_path equ 13
FLAG_V equ 14
FLAG_B equ 15
FLAG_C equ 16
FLAG_D equ 17
FLAG_L equ 18
FLAG_U equ 19
FLAG_S equ 20
FLAG_T equ 21
FLAG_h equ 22
LNDRV_O_CREATE equ 4*2
LNDRV_O_OPEN equ 4*3
LNDRV_O_DELETE equ 4*4
LNDRV_O_MKDIR equ 4*5
LNDRV_O_RMDIR equ 4*6
LNDRV_O_CHDIR equ 4*7
LNDRV_O_CHMOD equ 4*8
LNDRV_O_FILES equ 4*9
LNDRV_O_RENAME equ 4*10
LNDRV_O_NEWFILE equ 4*11
LNDRV_O_FATCHK equ 4*12
LNDRV_realpathcpy equ 4*16
LNDRV_LINK_FILES equ 4*17
LNDRV_OLD_LINK_FILES equ 4*18
LNDRV_link_nest_max equ 4*19
LNDRV_getrealpath equ 4*20
.text
start:
bra.s start1
dc.b '#HUPAIR',0
start1:
lea stack_bottom,a7 * A7 := スタックの底
DOS _VERNUM
cmp.w #REQUIRED_OSVER,d0
bcs dos_version_mismatch
lea $10(a0),a0 * A0 : PDBアドレス
move.l a7,d0
sub.l a0,d0
move.l d0,-(a7)
move.l a0,-(a7)
DOS _SETBLOCK
addq.l #8,a7
*
* 引数並び格納エリアを確保する
*
lea 1(a2),a0 * A0 := コマンドラインの文字列の先頭アドレス
bsr strlen * D0.L := コマンドラインの文字列の長さ
addq.l #1,d0
bsr malloc
bmi insufficient_memory
movea.l d0,a1 * A1 := 引数並び格納エリアの先頭アドレス
*
* バッファを確保する
*
move.l #$00ffffff,d0
bsr malloc
sub.l #$81000000,d0
cmp.l #1024,d0
blo no_buffer
move.l d0,d4 * D4.L : バッファサイズ
bsr malloc
bmi no_buffer
movea.l d0,a4 * A4 : バッファ
bra buffer_ok
no_buffer:
moveq #0,d4
buffer_ok:
*
* lndrv が組み込まれているかどうかを検査する
*
bsr getlnenv
move.l d0,lndrv
*
* 引数をデコードし,解釈する
*
bsr DecodeHUPAIR * 引数をデコードする
movea.l a1,a0 * A0 : 引数ポインタ
move.l d0,d7 * D7.L : 引数カウンタ
move.b #$ff,mode_mask
clr.b mode_plus
moveq #0,d5 * D5.L : フラグ
decode_opt_loop1:
tst.l d7
beq decode_opt_done
cmpi.b #'-',(a0)
bne decode_opt_done
tst.b 1(a0)
beq decode_opt_done
subq.l #1,d7
addq.l #1,a0
move.b (a0)+,d0
cmp.b #'-',d0
bne decode_opt_loop2
tst.b (a0)+
beq decode_opt_done
subq.l #1,a0
decode_opt_loop2:
cmp.b #'a',d0
beq set_option_a
moveq #FLAG_f,d1
cmp.b #'f',d0
beq set_option
moveq #FLAG_i,d1
cmp.b #'i',d0
beq set_option
moveq #FLAG_I,d1
cmp.b #'I',d0
beq set_option
moveq #FLAG_p,d1
cmp.b #'p',d0
beq set_option
moveq #FLAG_r,d1
cmp.b #'r',d0
beq set_option
moveq #FLAG_R,d1
cmp.b #'R',d0
beq set_option
moveq #FLAG_d,d1
cmp.b #'d',d0
beq set_option
moveq #FLAG_e,d1
cmp.b #'e',d0
beq set_option
moveq #FLAG_n,d1
cmp.b #'n',d0
beq set_option
moveq #FLAG_s,d1
cmp.b #'s',d0
beq set_option
moveq #FLAG_u,d1
cmp.b #'u',d0
beq set_option
moveq #FLAG_v,d1
cmp.b #'v',d0
beq set_option
moveq #FLAG_x,d1
cmp.b #'x',d0
beq set_option
moveq #FLAG_path,d1
cmp.b #'P',d0
beq set_option
moveq #FLAG_V,d1
cmp.b #'V',d0
beq set_option
moveq #FLAG_B,d1
cmp.b #'B',d0
beq set_option
moveq #FLAG_C,d1
cmp.b #'C',d0
beq set_option
moveq #FLAG_D,d1
cmp.b #'D',d0
beq set_option
moveq #FLAG_L,d1
cmp.b #'L',d0
beq set_option
moveq #FLAG_U,d1
cmp.b #'U',d0
beq set_option
moveq #FLAG_S,d1
cmp.b #'S',d0
beq set_option
moveq #FLAG_T,d1
cmp.b #'T',d0
beq set_option
moveq #FLAG_h,d1
cmp.b #'h',d0
beq set_option
cmp.b #'m',d0
beq decode_mode
moveq #1,d1
tst.b (a0)
beq bad_option_1
bsr issjis
bne bad_option_1
moveq #2,d1
bad_option_1:
move.l d1,-(a7)
pea -1(a0)
move.w #2,-(a7)
lea msg_illegal_option(pc),a0
bsr werror_myname_and_msg
DOS _WRITE
lea 10(a7),a7
bra usage
set_option_a:
bset #FLAG_d,d5
bset #FLAG_p,d5
bset #FLAG_r,d5
bra set_option_done
set_option:
bset d1,d5
set_option_done:
move.b (a0)+,d0
bne decode_opt_loop2
bra decode_opt_loop1
decode_mode:
tst.b (a0)
bne decode_mode_0
subq.l #1,d7
bcs too_few_args
addq.l #1,a0
decode_mode_0:
move.b (a0),d0
cmp.b #'0',d0
blo decode_symbolic_mode
cmp.b #'7',d0
bhi decode_symbolic_mode
* numeric mode
moveq #0,d1
scan_numeric_mode_loop:
move.b (a0)+,d0
beq scan_numeric_mode_done
sub.b #'0',d0
blo bad_arg
cmp.b #7,d0
bhi bad_arg
lsl.w #3,d1
or.b d0,d1
bra scan_numeric_mode_loop
scan_numeric_mode_done:
move.w d1,d0
lsr.w #3,d0
or.w d0,d1
lsr.w #3,d0
or.w d0,d1
moveq #0,d0
btst #1,d1
beq decode_numeric_mode_w_ok
bset #MODEBIT_RDO,d0
decode_numeric_mode_w_ok:
btst #0,d1
beq decode_numeric_mode_x_ok
bset #MODEBIT_EXE,d0
decode_numeric_mode_x_ok:
move.b d0,mode_plus
move.b #(MODEVAL_VOL|MODEVAL_DIR|MODEVAL_LNK|MODEVAL_ARC|MODEVAL_SYS|MODEVAL_HID),mode_mask
bra decode_opt_loop1
* symbolic mode
decode_symbolic_mode:
move.b #$ff,mode_mask
clr.b mode_plus
decode_symbolic_mode_loop1:
move.b (a0)+,d0
beq decode_opt_loop1
cmp.b #',',d0
beq decode_symbolic_mode_loop1
subq.l #1,a0
decode_symbolic_mode_loop2:
move.b (a0)+,d0
cmp.b #'u',d0
beq decode_symbolic_mode_loop2
cmp.b #'g',d0
beq decode_symbolic_mode_loop2
cmp.b #'o',d0
beq decode_symbolic_mode_loop2
cmp.b #'a',d0
beq decode_symbolic_mode_loop2
decode_symbolic_mode_loop3:
cmp.b #'+',d0
beq decode_symbolic_mode_plus
cmp.b #'-',d0
beq decode_symbolic_mode_minus
cmp.b #'=',d0
bne bad_arg
move.b #(MODEVAL_VOL|MODEVAL_DIR|MODEVAL_LNK),mode_mask
clr.b mode_plus
decode_symbolic_mode_plus:
bsr decode_symbolic_mode_sub
or.b d1,mode_plus
bra decode_symbolic_mode_continue
decode_symbolic_mode_minus:
bsr decode_symbolic_mode_sub
not.b d1
and.b d1,mode_mask
and.b d1,mode_plus
decode_symbolic_mode_continue:
tst.b d0
beq decode_opt_loop1
cmp.b #',',d0
beq decode_symbolic_mode_loop1
bra decode_symbolic_mode_loop3
decode_symbolic_mode_sub:
moveq #0,d1
decode_symbolic_mode_sub_loop:
move.b (a0)+,d0
moveq #MODEBIT_ARC,d2
cmp.b #'a',d0
beq decode_symbolic_mode_sub_set
moveq #MODEBIT_SYS,d2
cmp.b #'s',d0
beq decode_symbolic_mode_sub_set
moveq #MODEBIT_HID,d2
cmp.b #'h',d0
beq decode_symbolic_mode_sub_set
cmp.b #'r',d0
beq decode_symbolic_mode_sub_loop
moveq #MODEBIT_RDO,d2
cmp.b #'w',d0
beq decode_symbolic_mode_sub_set
moveq #MODEBIT_EXE,d2
cmp.b #'x',d0
beq decode_symbolic_mode_sub_set
rts
decode_symbolic_mode_sub_set:
bset d2,d1
bra decode_symbolic_mode_sub_loop
decode_opt_done:
subq.l #2,d7
bcs too_few_args
*
* targetを調べる
*
moveq #0,d6 * D6.W : エラー・コード
movea.l a0,a1 * A1 : 1st source
move.l d7,d0
find_target:
bsr strfor1
subq.l #1,d0
bcc find_target
* A0 : target
bsr strip_excessive_slashes
* targetがディレクトリであるかどうかを調べる
*
* ここでは、ディレクトリへのシンボリック・リンクも現実の
* ディレクトリと同等に扱う。-d オプションは影響しない。
bsr is_directory
bmi exit_program
bne cp_into_dir
btst #FLAG_path,d5
bne bad_target
tst.l d7
bne bad_target
*
* cp [ -ipr ] f1 f2
*
exg a0,a1 * A0 : 1st source, A1 : target (== destination)
bsr strip_excessive_slashes
bsr copy_file_or_directory_0
bra exit_program
****************
cp_into_dir:
*
* cp [ -ipr ] file ... dir
*
exg a0,a1 * A0 : 1st source, A1 : targetdir
cp_into_dir_loop:
movea.l a0,a2
bsr strfor1
exg a0,a2 * A2 : next arg
bsr strip_excessive_slashes
move.l #-1,drive
moveq #0,d0
bsr copy_into_dir_0
movea.l a2,a0
subq.l #1,d7
bcc cp_into_dir_loop
exit_program:
move.w d6,-(a7)
DOS _EXIT2
bad_target:
lea msg_not_a_directory(pc),a2
bsr lgetmode
bpl cp_error_exit
lea msg_nodir(pc),a2
cp_error_exit:
bsr werror_myname_word_colon_msg
bra exit_program
bad_arg:
lea msg_bad_arg(pc),a0
bra arg_error
too_few_args:
lea msg_too_few_args(pc),a0
arg_error:
bsr werror_myname_and_msg
usage:
lea msg_usage(pc),a0
bsr werror
moveq #1,d6
bra exit_program
dos_version_mismatch:
lea msg_dos_version_mismatch(pc),a0
bra cp_error_exit_3
insufficient_memory:
lea msg_no_memory(pc),a0
cp_error_exit_3:
bsr werror_myname_and_msg
moveq #3,d6
bra exit_program
*****************************************************************
* copy_into_dir_0, copy_into_dir_1
*
* A0 で示されるエントリを A1 で示されるディレクトリ下にコピーする
*
* CALL
* D0.L 再帰レベル
*
* RETURN
* A5 破壊
*****************************************************************
destination = -((((MAXPATH+1)+1)>>1)<<1)
copy_into_dir_autosize = -destination
copy_into_dir_0:
move.l #-1,source_mode
move.l #-1,source_time
st do_check_identical
copy_into_dir_1:
link a6,#destination
movem.l d0-d3/d5/d7/a0-a3,-(a7)
move.l d0,d7 * D7.L : 再帰レベル
move.l a0,copy_into_dir_sourceP
btst #FLAG_path,d5
bne copy_into_dir_skip_root
move.l a1,-(a7)
bsr headtail
movea.l a1,a0
movea.l (a7)+,a1
bra copy_into_dir_2
copy_into_dir_skip_root:
bsr skip_root
copy_into_dir_2:
movea.l a0,a2
*
* ここで,
* source: A:/s1/s2/s3
* | |
* A0 A0
* A2 A2
* (-P)
*
* targetdir: B:/t1/t2/t3
* |
* A1
*
* -L オプションが指定されているとき,A0以降に小文字が含まれていないかどうか
* チェックする
*
btst #FLAG_L,d5
beq check_name_case_ok
check_name_case:
move.b (a0)+,d0
beq check_name_case_ok
bsr islower
beq copy_into_dir_done
bsr issjis
bne check_name_case
tst.b (a0)+
bne check_name_case
check_name_case_ok:
*
* destination name を作る
*
lea destination(a6),a0
move.l #MAXPATH,d2
*
* ここで,
* source: A:/s1/s2/s3
* | |
* A2 A2
* (-P)
*
* targetdir: B:/t1/t2/t3
* |
* A1
*
* destination: ???
* |
* A0
*
* targetdir を destination にコピーする
*
exg a0,a1
bsr strlen
exg a0,a1
sub.l d0,d2
bcs copy_into_dir_too_long_path
bsr stpcpy
tst.b (a2)
beq copy_into_dir_makedestname_1
exg a0,a1
bsr skip_root
exg a0,a1
beq copy_into_dir_makedestname_1
subq.l #1,d2
bcs copy_into_dir_too_long_path
move.b #'/',(a0)+
copy_into_dir_makedestname_1:
move.l a0,copy_into_dir_destP
*
* ここで,
* source: A:/s1/s2/s3
* | |
* A2 A2
* (-P)
*
* destination: B:/t1/t2/t3/
* |
* A0
*
tst.b (a2)
beq copy_into_dir_makedestname_2
btst #FLAG_B,d5
bne copy_into_dir_makedestname_3
btst #FLAG_C,d5
bne copy_into_dir_makedestname_3
btst #FLAG_D,d5
bne copy_into_dir_makedestname_3
copy_into_dir_makedestname_2:
*
* A2以降を destination に追加する
*
exg a0,a2
bsr strlen
exg a0,a2
sub.l d0,d2
bcs copy_into_dir_too_long_path
movea.l a2,a1
bsr strcpy
bra destname_ok
copy_into_dir_makedestname_3:
movea.l a0,a3
*
* ここで,
* source: A:/s1/s2/s3
* | |
* A2 A2
* (-P)
*
* destination: B:/t1/t2/t3/
* |
* A3
*
copy_into_dir_makedestname_loop1:
movea.l a2,a0
bsr find_slashes
exg a0,a2
move.b d0,d3
clr.b (a2)
movea.l a0,a5
move.l a3,-(a7)
lea pathname_buf(pc),a3
moveq #0,d1
movea.l a0,a1
bsr isrel
beq makedestname_not_rel
exg a0,a3
bsr memmovi
exg a0,a3
bra makedestname_check
makedestname_not_rel:
moveq #8,d0
bsr makedestname_sub
beq makedestname_unadjustable_name
moveq #'.',d0
bsr strchr
beq makedestname_check
addq.l #1,a0
move.b #'.',(a3)+
moveq #3,d0
bsr makedestname_sub
bne makedestname_suffix_ok
subq.l #1,a3
moveq #1,d1
makedestname_suffix_ok:
moveq #'.',d0
bsr strchr
beq makedestname_check
makedestname_unadjustable_name:
moveq #-1,d1
makedestname_check:
clr.b (a3)
movea.l (a7)+,a3
lea pathname_buf(pc),a1
tst.b d1
beq makedestname_next
* unfit name
btst #FLAG_D,d5
bne copy_into_dir_done
btst #FLAG_C,d5
bne unfit_name
tst.b d1
bpl makedestname_next
unfit_name:
movea.l a5,a0
bsr werror_myname
movea.l copy_into_dir_sourceP,a0
move.b d3,(a2)
bsr werror
clr.b (a2)
lea msg_colon(pc),a0
bsr werror
ask_destname_1:
movea.l a5,a0
bsr werror
btst #FLAG_C,d5
bne ask_destname_2
lea msg_unadjustable_name(pc),a0
bsr werror
bra copy_into_dir_done
ask_destname_2:
lea msg_unfitname(pc),a0
bsr werror
btst #FLAG_n,d5
beq ask_destname_3
lea msg_will_ask(pc),a0
bsr werror
movea.l a5,a1
bra makedestname_next
ask_destname_3:
bsr werror_newline
ask_destname_4:
lea msg_destname(pc),a0
bsr werror
tst.b (a1)
beq ask_destname_5
lea msg_destname_1(pc),a0
bsr werror
movea.l a1,a0
bsr werror
ask_destname_5:
lea msg_destname_2(pc),a0
bsr werror
lea getsbuf(pc),a0
move.b #12,(a0)
move.l a0,-(a7)
DOS _GETS
addq.l #4,a7
bsr werror_newline
moveq #0,d0
move.b 1(a0),d0
bne check_answered_destname
tst.b (a1)
beq ask_destname_4
bra makedestname_next
check_answered_destname:
addq.l #2,a0
clr.b (a0,d0.l)
cmpi.b #'.',(a0)
beq copy_into_dir_done
movea.l a0,a5
sf d1
check_answered_destname_loop:
move.b (a0)+,d0
beq check_answered_destname_done
cmp.b #'.',d0
beq check_answered_destname_dot
cmp.b #'?',d0
beq ask_destname_1
cmp.b #'*',d0
beq ask_destname_1
cmp.b #'<',d0
beq ask_destname_1
cmp.b #'>',d0
beq ask_destname_1
cmp.b #':',d0
beq ask_destname_1
cmp.b #'/',d0
beq ask_destname_1
cmp.b #'\',d0
beq ask_destname_1
bsr issjis
bne check_answered_destname_loop
tst.b (a0)+
beq check_answered_destname_done
bra check_answered_destname_loop
check_answered_destname_dot:
tst.b d1
bne ask_destname_1
bsr strlen
subq.l #3,d0
bhi ask_destname_1
st d1
bra check_answered_destname_1
check_answered_destname_done:
tst.b d1
bne answered_destname_ok
check_answered_destname_1:
move.l a0,d0
subq.l #1,d0
sub.l a5,d0
beq ask_destname_1
subq.l #8,d0
bhi ask_destname_1
tst.b d1
bne check_answered_destname_loop
answered_destname_ok:
movea.l a5,a1
makedestname_next:
movea.l a1,a0
bsr strlen
sub.l d0,d2
bcs copy_into_dir_too_long_path
exg a0,a3
bsr memmovi
exg a0,a3
move.b d3,(a2)+
bne copy_into_dir_makedestname_loop1
clr.b (a3)
destname_ok:
*
* -U が指定されていれば大文字に変換する
*
btst #FLAG_U,d5
beq copy_into_dir_destname_ok
movea.l copy_into_dir_destP,a0
copy_into_dir_toupper:
move.b (a0),d0
beq copy_into_dir_destname_ok
bsr issjis
beq copy_into_dir_toupper_sjis
bsr toupper
move.b d0,(a0)+