Subversion Repositories SvarDOS

Rev

Rev 413 | Rev 418 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 413 Rev 415
1
/*
1
/*
2
 * copy
2
 * copy
3
 */
3
 */
4
 
4
 
5
/* /A - Used to copy ASCII files. Applies to the filename preceding it and to
5
/* /A - Used to copy ASCII files. Applies to the filename preceding it and to
6
 * all following filenames. Files will be copied until an end-of-file mark is
6
 * all following filenames. Files will be copied until an end-of-file mark is
7
 * encountered in the file being copied. If an end-of-file mark is encountered
7
 * encountered in the file being copied. If an end-of-file mark is encountered
8
 * in the file, the rest of the file is not copied. DOS will append an EOF
8
 * in the file, the rest of the file is not copied. DOS will append an EOF
9
 * mark at the end of the copied file.
9
 * mark at the end of the copied file.
10
 *
10
 *
11
 * /B - Used to copy binary files. Applies to the filename preceding it and to
11
 * /B - Used to copy binary files. Applies to the filename preceding it and to
12
 * all following filenames. Copied files will be read by size (according to
12
 * all following filenames. Copied files will be read by size (according to
13
 * the number of bytes indicated in the file`s directory listing). An EOF mark
13
 * the number of bytes indicated in the file`s directory listing). An EOF mark
14
 * is not placed at the end of the copied file.
14
 * is not placed at the end of the copied file.
15
 *
15
 *
16
 * /V - Checks after the copy to assure that a file was copied correctly. If
16
 * /V - Checks after the copy to assure that a file was copied correctly. If
17
 * the copy cannot be verified, the program will display an error message.
17
 * the copy cannot be verified, the program will display an error message.
18
 * Using this option will result in a slower copying process.
18
 * Using this option will result in a slower copying process.
19
 *
19
 *
20
 * special case: "COPY A+B+C+D" means "append B, C and D files to the A file"
20
 * special case: "COPY A+B+C+D" means "append B, C and D files to the A file"
21
 * if A does not exist, then "append C and D to B", etc.
21
 * if A does not exist, then "append C and D to B", etc.
22
 */
22
 */
23
 
23
 
24
struct copy_setup {
24
struct copy_setup {
25
  const char *src[64];
25
  const char *src[64];
26
  unsigned short src_count; /* how many sources are declared */
26
  unsigned short src_count; /* how many sources are declared */
27
  char dst[256];
27
  char dst[256];
28
  unsigned short dstlen;
28
  unsigned short dstlen;
29
  char src_asciimode[64];
29
  char src_asciimode[64];
30
  char dst_asciimode;
30
  char dst_asciimode;
31
  char last_asciimode; /* /A or /B impacts the file preceding it and becomes the new default for all files that follow */
31
  char last_asciimode; /* /A or /B impacts the file preceding it and becomes the new default for all files that follow */
32
  char verifyflag;
32
  char verifyflag;
33
  char lastitemwasplus;
33
  char lastitemwasplus;
34
  char databuf[BUFFER_SIZE - 1024];
34
  char databuf[BUFFER_SIZE - 1024];
35
};
35
};
36
 
36
 
37
 
37
 
38
/* appends a backslash if path is a directory
-
 
39
 * returns the (possibly updated) length of path */
-
 
40
static unsigned short cmd_copy_addbkslash_if_dir(char *path) {
-
 
41
  unsigned short len;
-
 
42
  int attr;
-
 
43
  for (len = 0; path[len] != 0; len++);
-
 
44
  if (len == 0) return(0);
-
 
45
  if (path[len - 1] == '\\') return(len);
-
 
46
  /* */
-
 
47
  attr = file_getattr(path);
-
 
48
  if ((attr > 0) && (attr & DOS_ATTR_DIR)) {
-
 
49
    path[len++] = '\\';
-
 
50
    path[len] = 0;
-
 
51
  }
-
 
52
  return(len);
-
 
53
}
-
 
54
 
-
 
55
 
-
 
56
/* copies src to dst, overwriting or appending to the destination.
38
/* copies src to dst, overwriting or appending to the destination.
57
 * - copy is performed in ASCII mode if asciiflag set (stop at first EOF in src
39
 * - copy is performed in ASCII mode if asciiflag set (stop at first EOF in src
58
 *   and append an EOF in dst).
40
 *   and append an EOF in dst).
59
 * - returns zero on success, DOS error code on error */
41
 * - returns zero on success, DOS error code on error */
60
unsigned short cmd_copy_internal(const char *dst, char dstascii, const char *src, char srcascii, unsigned char appendflag, void *buff, unsigned short buffsz) {
42
unsigned short cmd_copy_internal(const char *dst, char dstascii, const char *src, char srcascii, unsigned char appendflag, void *buff, unsigned short buffsz) {
61
  unsigned short errcode = 0;
43
  unsigned short errcode = 0;
62
  unsigned short srch = 0xffff, dsth = 0xffff;
44
  unsigned short srch = 0xffff, dsth = 0xffff;
63
  _asm {
45
  _asm {
64
 
46
 
65
    /* open src */
47
    /* open src */
66
    OPENSRC:
48
    OPENSRC:
67
    mov ax, 0x3d00 /* DOS 2+ -- open an existing file, read access mode */
49
    mov ax, 0x3d00 /* DOS 2+ -- open an existing file, read access mode */
68
    mov dx, src    /* ASCIIZ fname */
50
    mov dx, src    /* ASCIIZ fname */
69
    int 0x21       /* CF clear on success, handle in AX */
51
    int 0x21       /* CF clear on success, handle in AX */
70
    mov [srch], ax /* store src handle in memory */
52
    mov [srch], ax /* store src handle in memory */
71
 
53
 
72
    /* check appendflag so I know if I have to try opening dst for append */
54
    /* check appendflag so I know if I have to try opening dst for append */
73
    xor al, al
55
    xor al, al
74
    or al, [appendflag]
56
    or al, [appendflag]
75
    jz CREATEDST
57
    jz CREATEDST
76
 
58
 
77
    /* try opening dst first if appendflag set */
59
    /* try opening dst first if appendflag set */
78
    mov ax, 0x3d01 /* DOS 2+ -- open an existing file, write access mode */
60
    mov ax, 0x3d01 /* DOS 2+ -- open an existing file, write access mode */
79
    mov dx, dst    /* ASCIIZ fname */
61
    mov dx, dst    /* ASCIIZ fname */
80
    int 0x21       /* CF clear on success, handle in AX */
62
    int 0x21       /* CF clear on success, handle in AX */
81
    jc CREATEDST   /* failed to open file (file does not exist) */
63
    jc CREATEDST   /* failed to open file (file does not exist) */
82
    mov [dsth], ax /* store dst handle in memory */
64
    mov [dsth], ax /* store dst handle in memory */
83
 
65
 
84
    /* got file open, LSEEK to end of it now so future data is appended */
66
    /* got file open, LSEEK to end of it now so future data is appended */
85
    mov bx, ax     /* file handle in BX (was still in AX) */
67
    mov bx, ax     /* file handle in BX (was still in AX) */
86
    mov ax, 0x4202 /* DOS 2+ -- set file pointer to end of file + CX:DX */
68
    mov ax, 0x4202 /* DOS 2+ -- set file pointer to end of file + CX:DX */
87
    xor cx, cx     /* offset zero */
69
    xor cx, cx     /* offset zero */
88
    xor dx, dx     /* offset zero */
70
    xor dx, dx     /* offset zero */
89
    int 0x21       /* CF set on error */
71
    int 0x21       /* CF set on error */
90
    jc FAIL
72
    jc FAIL
91
    jmp COPY
73
    jmp COPY
92
 
74
 
93
    /* create dst */
75
    /* create dst */
94
    CREATEDST:
76
    CREATEDST:
95
    mov ah, 0x3c   /* DOS 2+ -- create a file */
77
    mov ah, 0x3c   /* DOS 2+ -- create a file */
96
    mov dx, dst
78
    mov dx, dst
97
    xor cx, cx     /* zero out attributes */
79
    xor cx, cx     /* zero out attributes */
98
    int 0x21       /* handle in AX on success, CF set on error */
80
    int 0x21       /* handle in AX on success, CF set on error */
99
    jc FAIL
81
    jc FAIL
100
    mov [dsth], ax /* store dst handle in memory */
82
    mov [dsth], ax /* store dst handle in memory */
101
 
83
 
102
    /* perform actual copy */
84
    /* perform actual copy */
103
    COPY:
85
    COPY:
104
    /* read a block from src */
86
    /* read a block from src */
105
    mov ah, 0x3f   /* DOS 2+ -- read from file */
87
    mov ah, 0x3f   /* DOS 2+ -- read from file */
106
    mov bx, [srch]
88
    mov bx, [srch]
107
    mov cx, [buffsz]
89
    mov cx, [buffsz]
108
    mov dx, [buff] /* DX points to buffer */
90
    mov dx, [buff] /* DX points to buffer */
109
    int 0x21       /* CF set on error, bytes read in AX (0=EOF) */
91
    int 0x21       /* CF set on error, bytes read in AX (0=EOF) */
110
    jc FAIL        /* abort on error */
92
    jc FAIL        /* abort on error */
111
    /* EOF? (ax == 0) */
93
    /* EOF? (ax == 0) */
112
    test ax, ax
94
    test ax, ax
113
    jz ENDOFFILE
95
    jz ENDOFFILE
114
    /* write block of AX bytes to dst */
96
    /* write block of AX bytes to dst */
115
    mov cx, ax     /* block length */
97
    mov cx, ax     /* block length */
116
    mov ah, 0x40   /* DOS 2+ -- write to file (CX bytes from DS:DX) */
98
    mov ah, 0x40   /* DOS 2+ -- write to file (CX bytes from DS:DX) */
117
    mov bx, [dsth] /* file handle */
99
    mov bx, [dsth] /* file handle */
118
    /* mov dx, [buff] */ /* DX points to buffer already */
100
    /* mov dx, [buff] */ /* DX points to buffer already */
119
    int 0x21       /* CF clear and AX=CX on success */
101
    int 0x21       /* CF clear and AX=CX on success */
120
    jc FAIL
102
    jc FAIL
121
    cmp ax, cx     /* sould be equal, otherwise failed */
103
    cmp ax, cx     /* sould be equal, otherwise failed */
122
    mov ax, 0x08   /* preset to DOS error "Insufficient memory" */
104
    mov ax, 0x08   /* preset to DOS error "Insufficient memory" */
123
    jne FAIL
105
    jne FAIL
124
    jmp COPY
106
    jmp COPY
125
 
107
 
126
    ENDOFFILE:
108
    ENDOFFILE:
127
    /* if dst ascii mode -> add an EOF (ASCII mode not supported for the time being) */
109
    /* if dst ascii mode -> add an EOF (ASCII mode not supported for the time being) */
128
 
110
 
129
    jmp CLOSESRC
111
    jmp CLOSESRC
130
 
112
 
131
    FAIL:
113
    FAIL:
132
    mov [errcode], ax
114
    mov [errcode], ax
133
 
115
 
134
    CLOSESRC:
116
    CLOSESRC:
135
    /* close src and dst */
117
    /* close src and dst */
136
    mov bx, [srch]
118
    mov bx, [srch]
137
    cmp bx, 0xffff
119
    cmp bx, 0xffff
138
    je CLOSEDST
120
    je CLOSEDST
139
    mov ah, 0x3e   /* DOS 2+ -- close a file handle */
121
    mov ah, 0x3e   /* DOS 2+ -- close a file handle */
140
    int 0x21
122
    int 0x21
141
 
123
 
142
    CLOSEDST:
124
    CLOSEDST:
143
    mov bx, [dsth]
125
    mov bx, [dsth]
144
    cmp bx, 0xffff
126
    cmp bx, 0xffff
145
    je DONE
127
    je DONE
146
    mov ah, 0x3e   /* DOS 2+ -- close a file handle */
128
    mov ah, 0x3e   /* DOS 2+ -- close a file handle */
147
    int 0x21
129
    int 0x21
148
 
130
 
149
    DONE:
131
    DONE:
150
  }
132
  }
151
  return(errcode);
133
  return(errcode);
152
}
134
}
153
 
135
 
154
 
136
 
155
static int cmd_copy(struct cmd_funcparam *p) {
137
static int cmd_copy(struct cmd_funcparam *p) {
156
  struct copy_setup *setup = (void *)(p->BUFFER);
138
  struct copy_setup *setup = (void *)(p->BUFFER);
157
  unsigned short i;
139
  unsigned short i;
158
  unsigned short copiedcount_in = 0, copiedcount_out = 0; /* number of input/output copied files */
140
  unsigned short copiedcount_in = 0, copiedcount_out = 0; /* number of input/output copied files */
159
  struct DTA *dta = (void *)0x80; /* use DTA at default location in PSP */
141
  struct DTA *dta = (void *)0x80; /* use DTA at default location in PSP */
160
 
142
 
161
  if (cmd_ishlp(p)) {
143
  if (cmd_ishlp(p)) {
162
    outputnl("Copies one or more files to another location.");
144
    outputnl("Copies one or more files to another location.");
163
    outputnl("");
145
    outputnl("");
164
    outputnl("COPY [/A|/B] source [/A|/B] [+source [/A|/B] [+...]] [destination [/A|/B]] [/V]");
146
    outputnl("COPY [/A|/B] source [/A|/B] [+source [/A|/B] [+...]] [destination [/A|/B]] [/V]");
165
    outputnl("");
147
    outputnl("");
166
    outputnl("source       Specifies the file or files to be copied");
148
    outputnl("source       Specifies the file or files to be copied");
167
    outputnl("/A           Indicates an ASCII text file");
149
    outputnl("/A           Indicates an ASCII text file");
168
    outputnl("/B           Indicates a binary file");
150
    outputnl("/B           Indicates a binary file");
169
    outputnl("destination  Specifies the directory and/or filename for the new file(s)");
151
    outputnl("destination  Specifies the directory and/or filename for the new file(s)");
170
    outputnl("/V           Verifies that new files are written correctly");
152
    outputnl("/V           Verifies that new files are written correctly");
171
    outputnl("");
153
    outputnl("");
172
    outputnl("To append files, specify a single file for destination, but multiple files");
154
    outputnl("To append files, specify a single file for destination, but multiple files");
173
    outputnl("for source (using wildcards or file1+file2+file3 format).");
155
    outputnl("for source (using wildcards or file1+file2+file3 format).");
174
    outputnl("");
156
    outputnl("");
175
    outputnl("NOTE: /A and /B are no-ops (ignored), provided only for compatibility reasons.");
157
    outputnl("NOTE: /A and /B are no-ops (ignored), provided only for compatibility reasons.");
176
    return(-1);
158
    return(-1);
177
  }
159
  }
178
 
160
 
179
  /* parse cmdline and fill the setup struct accordingly */
161
  /* parse cmdline and fill the setup struct accordingly */
180
 
162
 
181
  memset(setup, 0, sizeof(*setup));
163
  memset(setup, 0, sizeof(*setup));
182
 
164
 
183
  for (i = 0; i < p->argc; i++) {
165
  for (i = 0; i < p->argc; i++) {
184
 
166
 
185
    /* switch? */
167
    /* switch? */
186
    if (p->argv[i][0] == '/') {
168
    if (p->argv[i][0] == '/') {
187
      if ((imatch(p->argv[i], "/a")) || (imatch(p->argv[i], "/b"))) {
169
      if ((imatch(p->argv[i], "/a")) || (imatch(p->argv[i], "/b"))) {
188
        setup->last_asciimode = 'b';
170
        setup->last_asciimode = 'b';
189
        if (imatch(p->argv[i], "/a")) setup->last_asciimode = 'a';
171
        if (imatch(p->argv[i], "/a")) setup->last_asciimode = 'a';
190
        /* */
172
        /* */
191
        if (setup->dst[0] != 0) {
173
        if (setup->dst[0] != 0) {
192
          setup->dst_asciimode = setup->last_asciimode;
174
          setup->dst_asciimode = setup->last_asciimode;
193
        } else if (setup->src_count != 0) {
175
        } else if (setup->src_count != 0) {
194
          setup->src_asciimode[setup->src_count - 1] = setup->last_asciimode;
176
          setup->src_asciimode[setup->src_count - 1] = setup->last_asciimode;
195
        }
177
        }
196
      } else if (imatch(p->argv[i], "/v")) {
178
      } else if (imatch(p->argv[i], "/v")) {
197
        setup->verifyflag = 1;
179
        setup->verifyflag = 1;
198
      } else {
180
      } else {
199
        outputnl("Invalid switch");
181
        outputnl("Invalid switch");
200
        return(-1);
182
        return(-1);
201
      }
183
      }
202
      continue;
184
      continue;
203
    }
185
    }
204
 
186
 
205
    /* not a switch - must be either a source, a destination or a + */
187
    /* not a switch - must be either a source, a destination or a + */
206
    if (p->argv[i][0] == '+') {
188
    if (p->argv[i][0] == '+') {
207
      /* a plus cannot appear after destination or before first source */
189
      /* a plus cannot appear after destination or before first source */
208
      if ((setup->dst[0] != 0) || (setup->src_count == 0)) {
190
      if ((setup->dst[0] != 0) || (setup->src_count == 0)) {
209
        outputnl("Invalid syntax");
191
        outputnl("Invalid syntax");
210
        return(-1);
192
        return(-1);
211
      }
193
      }
212
      setup->lastitemwasplus = 1;
194
      setup->lastitemwasplus = 1;
213
      /* a plus may be immediately followed by a filename - if so, emulate
195
      /* a plus may be immediately followed by a filename - if so, emulate
214
       * a new argument */
196
       * a new argument */
215
      if (p->argv[i][1] != 0) {
197
      if (p->argv[i][1] != 0) {
216
        p->argv[i] += 1;
198
        p->argv[i] += 1;
217
        i--;
199
        i--;
218
      }
200
      }
219
      continue;
201
      continue;
220
    }
202
    }
221
 
203
 
222
    /* src? (first non-switch or something that follows a +) */
204
    /* src? (first non-switch or something that follows a +) */
223
    if ((setup->lastitemwasplus) || (setup->src_count == 0)) {
205
    if ((setup->lastitemwasplus) || (setup->src_count == 0)) {
224
      setup->src[setup->src_count] = p->argv[i];
206
      setup->src[setup->src_count] = p->argv[i];
225
      setup->src_asciimode[setup->src_count] = setup->last_asciimode;
207
      setup->src_asciimode[setup->src_count] = setup->last_asciimode;
226
      setup->src_count++;
208
      setup->src_count++;
227
      setup->lastitemwasplus = 0;
209
      setup->lastitemwasplus = 0;
228
      continue;
210
      continue;
229
    }
211
    }
230
 
212
 
231
    /* must be a dst then */
213
    /* must be a dst then */
232
    if (setup->dst[0] != 0) {
214
    if (setup->dst[0] != 0) {
233
      outputnl("Invalid syntax");
215
      outputnl("Invalid syntax");
234
      return(-1);
216
      return(-1);
235
    }
217
    }
236
    if (file_truename(p->argv[i], setup->dst) != 0) {
218
    if (file_truename(p->argv[i], setup->dst) != 0) {
237
      outputnl("Invalid destination");
219
      outputnl("Invalid destination");
238
      return(-1);
220
      return(-1);
239
    }
221
    }
240
    setup->dst_asciimode = setup->last_asciimode;
222
    setup->dst_asciimode = setup->last_asciimode;
241
    /* if dst is a directory then append a backslash */
223
    /* if dst is a directory then append a backslash */
242
    setup->dstlen = cmd_copy_addbkslash_if_dir(setup->dst);
224
    setup->dstlen = path_appendbkslash_if_dir(setup->dst);
243
  }
225
  }
244
 
226
 
245
  /* DEBUG: output setup content ("if 1" to enable) */
227
  /* DEBUG: output setup content ("if 1" to enable) */
246
  #if 1
228
  #if 1
247
  printf("src: ");
229
  printf("src: ");
248
  for (i = 0; i < setup->src_count; i++) {
230
  for (i = 0; i < setup->src_count; i++) {
249
    if (i != 0) printf(", ");
231
    if (i != 0) printf(", ");
250
    printf("%s [%c]", setup->src[i], setup->src_asciimode[i]);
232
    printf("%s [%c]", setup->src[i], setup->src_asciimode[i]);
251
  }
233
  }
252
  printf("\r\n");
234
  printf("\r\n");
253
  printf("dst: %s [%c]\r\n", setup->dst, setup->dst_asciimode);
235
  printf("dst: %s [%c]\r\n", setup->dst, setup->dst_asciimode);
254
  printf("verify: %s\r\n", (setup->verifyflag)?"ON":"OFF");
236
  printf("verify: %s\r\n", (setup->verifyflag)?"ON":"OFF");
255
  #endif
237
  #endif
256
 
238
 
257
  /* must have at least one source */
239
  /* must have at least one source */
258
  if (setup->src_count == 0) {
240
  if (setup->src_count == 0) {
259
    outputnl("Required parameter missing");
241
    outputnl("Required parameter missing");
260
    return(-1);
242
    return(-1);
261
  }
243
  }
262
 
244
 
263
  /* perform the operation based on setup directives:
245
  /* perform the operation based on setup directives:
264
   * iterate over every source and copy it to dest */
246
   * iterate over every source and copy it to dest */
265
 
247
 
266
  for (i = 0; i < setup->src_count; i++) {
248
  for (i = 0; i < setup->src_count; i++) {
267
    unsigned short t;
249
    unsigned short t;
268
    unsigned short databuflen;
250
    unsigned short databuflen;
269
    unsigned short pathendoffset;
251
    unsigned short pathendoffset;
270
 
252
 
271
    /* resolve truename of src and write it to buffer */
253
    /* resolve truename of src and write it to buffer */
272
    t = file_truename(setup->src[i], setup->databuf);
254
    t = file_truename(setup->src[i], setup->databuf);
273
    if (t != 0) {
255
    if (t != 0) {
274
      output(setup->src[i]);
256
      output(setup->src[i]);
275
      output(" - ");
257
      output(" - ");
276
      outputnl(doserr(t));
258
      outputnl(doserr(t));
277
      continue;
259
      continue;
278
    }
260
    }
279
    databuflen = strlen(setup->databuf); /* remember databuf length */
261
    databuflen = strlen(setup->databuf); /* remember databuf length */
280
 
262
 
281
    /* if length zero, skip (not sure why this would be possible, though) */
263
    /* if length zero, skip (not sure why this would be possible, though) */
282
    if (databuflen == 0) continue;
264
    if (databuflen == 0) continue;
283
 
265
 
284
    /* if src does not end with a backslash AND it is a directory then append a backslash */
266
    /* if src does not end with a backslash AND it is a directory then append a backslash */
285
    databuflen = cmd_copy_addbkslash_if_dir(setup->databuf);
267
    databuflen = path_appendbkslash_if_dir(setup->databuf);
286
 
268
 
287
    /* if src ends with a '\' then append *.* */
269
    /* if src ends with a '\' then append *.* */
288
    if (setup->databuf[databuflen - 1] == '\\') {
270
    if (setup->databuf[databuflen - 1] == '\\') {
289
      strcat(setup->databuf, "*.*");
271
      strcat(setup->databuf, "*.*");
290
    }
272
    }
291
 
273
 
292
    /* remember where the path in databuf ends */
274
    /* remember where the path in databuf ends */
293
    for (t = 0; setup->databuf[t] != 0; t++) {
275
    for (t = 0; setup->databuf[t] != 0; t++) {
294
      if (setup->databuf[t] == '\\') pathendoffset = t + 1;
276
      if (setup->databuf[t] == '\\') pathendoffset = t + 1;
295
    }
277
    }
296
 
278
 
297
    /* */
279
    /* */
298
    if (findfirst(dta, setup->databuf, 0) != 0) {
280
    if (findfirst(dta, setup->databuf, 0) != 0) {
299
      continue;
281
      continue;
300
    }
282
    }
301
 
283
 
302
    do {
284
    do {
303
      char appendflag;
285
      char appendflag;
304
      if (dta->attr & DOS_ATTR_DIR) continue; /* skip directories */
286
      if (dta->attr & DOS_ATTR_DIR) continue; /* skip directories */
305
 
287
 
306
      /* compute full path/name of the file */
288
      /* compute full path/name of the file */
307
      strcpy(setup->databuf + pathendoffset, dta->fname);
289
      strcpy(setup->databuf + pathendoffset, dta->fname);
308
 
290
 
309
      /* if there was no destination, then YOU are the destination now!
291
      /* if there was no destination, then YOU are the destination now!
310
       * this handles situations like COPY a.txt+b.txt+c.txt */
292
       * this handles situations like COPY a.txt+b.txt+c.txt */
311
      if (setup->dst[0] == NULL) {
293
      if (setup->dst[0] == NULL) {
312
        strcpy(setup->dst, setup->databuf);
294
        strcpy(setup->dst, setup->databuf);
313
        setup->dstlen = strlen(setup->dst);
295
        setup->dstlen = strlen(setup->dst);
314
        copiedcount_in++;
296
        copiedcount_in++;
315
        copiedcount_out++;
297
        copiedcount_out++;
316
        continue;
298
        continue;
317
      }
299
      }
318
 
300
 
319
      /* is dst ending with a backslash? then append fname to it */
301
      /* is dst ending with a backslash? then append fname to it */
320
      if (setup->dst[setup->dstlen - 1] == '\\') strcpy(setup->dst + setup->dstlen, dta->fname);
302
      if (setup->dst[setup->dstlen - 1] == '\\') strcpy(setup->dst + setup->dstlen, dta->fname);
321
 
303
 
322
      /* now databuf contains the full source and dst contains the full dest... COPY TIME! */
304
      /* now databuf contains the full source and dst contains the full dest... COPY TIME! */
323
 
305
 
324
      /* if dst file exists already -> overwrite it or append?
306
      /* if dst file exists already -> overwrite it or append?
325
          - if dst is a dir (dstlen-1 points at a \\) -> overwrite
307
          - if dst is a dir (dstlen-1 points at a \\) -> overwrite
326
          - otherwise: if copiedcount_in==0 overwrite, else append */
308
          - otherwise: if copiedcount_in==0 overwrite, else append */
327
      output(setup->databuf);
309
      output(setup->databuf);
328
      if ((setup->dst[setup->dstlen - 1] == '\\') || (copiedcount_in == 0)) {
310
      if ((setup->dst[setup->dstlen - 1] == '\\') || (copiedcount_in == 0)) {
329
        appendflag = 0;
311
        appendflag = 0;
330
        output(" > ");
312
        output(" > ");
331
        copiedcount_out++;
313
        copiedcount_out++;
332
      } else {
314
      } else {
333
        appendflag = 1;
315
        appendflag = 1;
334
        output(" >> ");
316
        output(" >> ");
335
      }
317
      }
336
      outputnl(setup->dst);
318
      outputnl(setup->dst);
337
 
319
 
338
      t = cmd_copy_internal(setup->dst, 0, setup->databuf, 0, appendflag, setup->databuf, sizeof(setup->databuf));
320
      t = cmd_copy_internal(setup->dst, 0, setup->databuf, 0, appendflag, setup->databuf, sizeof(setup->databuf));
339
      if (t != 0) {
321
      if (t != 0) {
340
        outputnl(doserr(t));
322
        outputnl(doserr(t));
341
        return(-1);
323
        return(-1);
342
      }
324
      }
343
 
325
 
344
      copiedcount_in++;
326
      copiedcount_in++;
345
    } while (findnext(dta) == 0);
327
    } while (findnext(dta) == 0);
346
 
328
 
347
  }
329
  }
348
 
330
 
349
  sprintf(setup->databuf, "%u file(s) copied", copiedcount_out);
331
  sprintf(setup->databuf, "%u file(s) copied", copiedcount_out);
350
  outputnl(setup->databuf);
332
  outputnl(setup->databuf);
351
 
333
 
352
  return(-1);
334
  return(-1);
353
}
335
}
354
 
336