Subversion Repositories SvarDOS

Rev

Rev 409 | Rev 413 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 409 Rev 412
Line 51... Line 51...
51
  }
51
  }
52
  return(len);
52
  return(len);
53
}
53
}
54
 
54
 
55
 
55
 
-
 
56
/* 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
-
 
58
 *   and append an EOF in dst).
-
 
59
 * - 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) {
-
 
61
  unsigned short errcode = 0;
-
 
62
  unsigned short srch = 0xffff, dsth = 0xffff;
-
 
63
  _asm {
-
 
64
 
-
 
65
    /* open src */
-
 
66
    OPENSRC:
-
 
67
    mov ax, 0x3d00 /* DOS 2+ -- open an existing file, read access mode */
-
 
68
    mov dx, src    /* ASCIIZ fname */
-
 
69
    int 0x21       /* CF clear on success, handle in AX */
-
 
70
    mov [srch], ax /* store src handle in memory */
-
 
71
 
-
 
72
    /* check appendflag so I know if I have to try opening dst for append */
-
 
73
    xor al, al
-
 
74
    or al, [appendflag]
-
 
75
    jz CREATEDST
-
 
76
 
-
 
77
    /* try opening dst first if appendflag set */
-
 
78
    mov ax, 0x3d01 /* DOS 2+ -- open an existing file, write access mode */
-
 
79
    mov dx, dst    /* ASCIIZ fname */
-
 
80
    int 0x21       /* CF clear on success, handle in AX */
-
 
81
    jc CREATEDST   /* failed to open file (file does not exist) */
-
 
82
    mov [dsth], ax /* store dst handle in memory */
-
 
83
 
-
 
84
    /* 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) */
-
 
86
    mov ax, 0x4202 /* DOS 2+ -- set file pointer to end of file + CX:DX */
-
 
87
    xor cx, cx     /* offset zero */
-
 
88
    xor dx, dx     /* offset zero */
-
 
89
    int 0x21       /* CF set on error */
-
 
90
    jc FAIL
-
 
91
    jmp COPY
-
 
92
 
-
 
93
    /* create dst */
-
 
94
    CREATEDST:
-
 
95
    mov ah, 0x3c   /* DOS 2+ -- create a file */
-
 
96
    mov dx, dst
-
 
97
    xor cx, cx     /* zero out attributes */
-
 
98
    int 0x21       /* handle in AX on success, CF set on error */
-
 
99
    jc FAIL
-
 
100
    mov [dsth], ax /* store dst handle in memory */
-
 
101
 
-
 
102
    /* perform actual copy */
-
 
103
    COPY:
-
 
104
    /* read a block from src */
-
 
105
    mov ah, 0x3f   /* DOS 2+ -- read from file */
-
 
106
    mov bx, [srch]
-
 
107
    mov cx, [buffsz]
-
 
108
    mov dx, [buff] /* DX points to buffer */
-
 
109
    int 0x21       /* CF set on error, bytes read in AX (0=EOF) */
-
 
110
    jc FAIL        /* abort on error */
-
 
111
    /* EOF? (ax == 0) */
-
 
112
    cmp ax, 0
-
 
113
    je ENDOFFILE
-
 
114
    /* write block of AX bytes to dst */
-
 
115
    mov cx, ax     /* block length */
-
 
116
    mov ah, 0x40   /* DOS 2+ -- write to file (CX bytes from DS:DX) */
-
 
117
    mov bx, [dsth] /* file handle */
-
 
118
    /* mov dx, [buff] */ /* DX points to buffer already */
-
 
119
    int 0x21       /* CF clear and AX=CX on success */
-
 
120
    jc FAIL
-
 
121
    cmp ax, cx     /* sould be equal, otherwise failed */
-
 
122
    mov ax, 0x08   /* preset to DOS error "Insufficient memory" */
-
 
123
    jne FAIL
-
 
124
    jmp COPY
-
 
125
 
-
 
126
    /* if dst ascii mode -> add an EOF */
-
 
127
    ENDOFFILE:
-
 
128
    /* TODO */
-
 
129
 
-
 
130
    jmp CLOSESRC
-
 
131
 
-
 
132
    FAIL:
-
 
133
    mov [errcode], ax
-
 
134
 
-
 
135
    CLOSESRC:
-
 
136
    /* close src and dst */
-
 
137
    mov bx, [srch]
-
 
138
    cmp bx, 0xffff
-
 
139
    je CLOSEDST
-
 
140
    mov ah, 0x3e   /* DOS 2+ -- close a file handle */
-
 
141
    int 0x21
-
 
142
 
-
 
143
    CLOSEDST:
-
 
144
    mov bx, [dsth]
-
 
145
    cmp bx, 0xffff
-
 
146
    je DONE
-
 
147
    mov ah, 0x3e   /* DOS 2+ -- close a file handle */
-
 
148
    int 0x21
-
 
149
 
-
 
150
    DONE:
-
 
151
  }
-
 
152
  return(errcode);
-
 
153
}
-
 
154
 
-
 
155
 
56
static int cmd_copy(struct cmd_funcparam *p) {
156
static int cmd_copy(struct cmd_funcparam *p) {
57
  struct copy_setup *setup = (void *)(p->BUFFER);
157
  struct copy_setup *setup = (void *)(p->BUFFER);
58
  unsigned short i;
158
  unsigned short i;
59
  unsigned short copiedcount_in = 0, copiedcount_out = 0; /* number of input/output copied files */
159
  unsigned short copiedcount_in = 0, copiedcount_out = 0; /* number of input/output copied files */
60
  struct DTA *dta = (void *)0x80; /* use DTA at default location in PSP */
160
  struct DTA *dta = (void *)0x80; /* use DTA at default location in PSP */
Line 197... Line 297...
197
    if (findfirst(dta, setup->databuf, 0) != 0) {
297
    if (findfirst(dta, setup->databuf, 0) != 0) {
198
      continue;
298
      continue;
199
    }
299
    }
200
 
300
 
201
    do {
301
    do {
-
 
302
      char appendflag;
202
      if (dta->attr & DOS_ATTR_DIR) continue; /* skip directories */
303
      if (dta->attr & DOS_ATTR_DIR) continue; /* skip directories */
203
 
304
 
204
      /* compute full path/name of the file */
305
      /* compute full path/name of the file */
205
      strcpy(setup->databuf + pathendoffset, dta->fname);
306
      strcpy(setup->databuf + pathendoffset, dta->fname);
206
 
307
 
Line 222... Line 323...
222
      /* if dst file exists already -> overwrite it or append?
323
      /* if dst file exists already -> overwrite it or append?
223
          - if dst is a dir (dstlen-1 points at a \\) -> overwrite
324
          - if dst is a dir (dstlen-1 points at a \\) -> overwrite
224
          - otherwise: if copiedcount_in==0 overwrite, else append */
325
          - otherwise: if copiedcount_in==0 overwrite, else append */
225
      output(setup->databuf);
326
      output(setup->databuf);
226
      if ((setup->dst[setup->dstlen - 1] == '\\') || (copiedcount_in == 0)) {
327
      if ((setup->dst[setup->dstlen - 1] == '\\') || (copiedcount_in == 0)) {
-
 
328
        appendflag = 0;
227
        output(" > ");
329
        output(" > ");
228
        copiedcount_out++;
330
        copiedcount_out++;
229
      } else {
331
      } else {
-
 
332
        appendflag = 1;
230
        output(" >> ");
333
        output(" >> ");
231
      }
334
      }
232
      outputnl(setup->dst);
335
      outputnl(setup->dst);
233
 
336
 
-
 
337
      t = cmd_copy_internal(setup->dst, 0, setup->databuf, 0, appendflag, setup->databuf, sizeof(setup->databuf));
-
 
338
      if (t != 0) {
-
 
339
        outputnl(doserr(t));
-
 
340
        return(-1);
-
 
341
      }
-
 
342
 
234
      copiedcount_in++;
343
      copiedcount_in++;
235
    } while (findnext(dta) == 0);
344
    } while (findnext(dta) == 0);
236
 
345
 
237
  }
346
  }
238
 
347