Subversion Repositories SvarDOS

Rev

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

Rev 406 Rev 421
-
 
1
/* This file is part of the SvarCOM project and is published under the terms
-
 
2
 * of the MIT license.
-
 
3
 *
-
 
4
 * Copyright (C) 2021 Mateusz Viste
-
 
5
 *
-
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a
-
 
7
 * copy of this software and associated documentation files (the "Software"),
-
 
8
 * to deal in the Software without restriction, including without limitation
-
 
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-
 
10
 * and/or sell copies of the Software, and to permit persons to whom the
-
 
11
 * Software is furnished to do so, subject to the following conditions:
-
 
12
 *
-
 
13
 * The above copyright notice and this permission notice shall be included in
-
 
14
 * all copies or substantial portions of the Software.
-
 
15
 *
-
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-
 
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-
 
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-
 
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-
 
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-
 
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-
 
22
 * DEALINGS IN THE SOFTWARE.
-
 
23
 */
-
 
24
 
1
/*
25
/*
2
 * rename/ren
26
 * rename/ren
3
 */
27
 */
4
 
28
 
5
static int cmd_rename(struct cmd_funcparam *p) {
29
static int cmd_rename(struct cmd_funcparam *p) {
6
  char *src = p->BUFFER;
30
  char *src = p->BUFFER;
7
  char *dst = p->BUFFER + (BUFFER_SIZE / 4);
31
  char *dst = p->BUFFER + (BUFFER_SIZE / 4);
8
  char *buff1 = p->BUFFER + (BUFFER_SIZE / 4 * 2);
32
  char *buff1 = p->BUFFER + (BUFFER_SIZE / 4 * 2);
9
  char *buff2 = p->BUFFER + (BUFFER_SIZE / 4 * 3);
33
  char *buff2 = p->BUFFER + (BUFFER_SIZE / 4 * 3);
10
  unsigned short i, fnameoffset;
34
  unsigned short i, fnameoffset;
11
  struct DTA *dta = (void *)0x80; /* use default DTA in PSP */
35
  struct DTA *dta = (void *)0x80; /* use default DTA in PSP */
12
 
36
 
13
  if (cmd_ishlp(p)) {
37
  if (cmd_ishlp(p)) {
14
    outputnl("Renames a file or files");
38
    outputnl("Renames a file or files");
15
    outputnl("");
39
    outputnl("");
16
    outputnl("RENAME [drive:][path]filename1 filename2");
40
    outputnl("RENAME [drive:][path]filename1 filename2");
17
    outputnl("REN [drive:][path]filename1 filename2");
41
    outputnl("REN [drive:][path]filename1 filename2");
18
    outputnl("");
42
    outputnl("");
19
    outputnl("Note that you cannot specify a new drive or path for your destination file.");
43
    outputnl("Note that you cannot specify a new drive or path for your destination file.");
20
    outputnl("Use MOVE to rename a directory, or to move files from one directory to another.");
44
    outputnl("Use MOVE to rename a directory, or to move files from one directory to another.");
21
    return(-1);
45
    return(-1);
22
  }
46
  }
23
 
47
 
24
  /* I expect exactly two arguments */
48
  /* I expect exactly two arguments */
25
  if (p->argc != 2) {
49
  if (p->argc != 2) {
26
    outputnl("Invalid syntax");
50
    outputnl("Invalid syntax");
27
    return(-1);
51
    return(-1);
28
  }
52
  }
29
 
53
 
30
  /* convert src to truename format */
54
  /* convert src to truename format */
31
  i = file_truename(p->argv[0], src);
55
  i = file_truename(p->argv[0], src);
32
  if (i != 0) {
56
  if (i != 0) {
33
    outputnl(doserr(i));
57
    outputnl(doserr(i));
34
    return(-1);
58
    return(-1);
35
  }
59
  }
36
 
60
 
37
  /* copy src path to buffers and remember where the filename starts */
61
  /* copy src path to buffers and remember where the filename starts */
38
  fnameoffset = 0;
62
  fnameoffset = 0;
39
  for (i = 0;; i++) {
63
  for (i = 0;; i++) {
40
    buff1[i] = src[i];
64
    buff1[i] = src[i];
41
    buff2[i] = src[i];
65
    buff2[i] = src[i];
42
    if (buff1[i] == '\\') fnameoffset = i + 1;
66
    if (buff1[i] == '\\') fnameoffset = i + 1;
43
    if (buff1[i] == 0) break;
67
    if (buff1[i] == 0) break;
44
  }
68
  }
45
 
69
 
46
  /* now append dst filename to the buffer and validate it: cannot contain backslash, slash or ':' */
70
  /* now append dst filename to the buffer and validate it: cannot contain backslash, slash or ':' */
47
  for (i = 0;; i++) {
71
  for (i = 0;; i++) {
48
    switch (p->argv[1][i]) {
72
    switch (p->argv[1][i]) {
49
      case ':':
73
      case ':':
50
      case '\\':
74
      case '\\':
51
      case '/':
75
      case '/':
52
        outputnl("Invalid destination");
76
        outputnl("Invalid destination");
53
        return(-1);
77
        return(-1);
54
    }
78
    }
55
    buff1[fnameoffset + i] = p->argv[1][i];
79
    buff1[fnameoffset + i] = p->argv[1][i];
56
    if (buff1[fnameoffset + i] == 0) break;
80
    if (buff1[fnameoffset + i] == 0) break;
57
  }
81
  }
58
 
82
 
59
  /* apply truename to dest to normalize wildcards into ? chars */
83
  /* apply truename to dest to normalize wildcards into ? chars */
60
  i = file_truename(buff1, dst);
84
  i = file_truename(buff1, dst);
61
  if (i != 0) {
85
  if (i != 0) {
62
    outputnl(doserr(i));
86
    outputnl(doserr(i));
63
    return(-1);
87
    return(-1);
64
  }
88
  }
65
 
89
 
66
  /* we're good to go, src and dst should look somehow like that now:
90
  /* we're good to go, src and dst should look somehow like that now:
67
   * src   =   C:\TEMP\PATH\FILE????.TXT
91
   * src   =   C:\TEMP\PATH\FILE????.TXT
68
   * dst   =   C:\TEMP\PATH\FILE????.DOC
92
   * dst   =   C:\TEMP\PATH\FILE????.DOC
69
   * buff1 =   C:\TEMP\PATH\
93
   * buff1 =   C:\TEMP\PATH\
70
   * buff2 =   C:\TEMP\PATH\
94
   * buff2 =   C:\TEMP\PATH\
71
   * fnameoffset = 13
95
   * fnameoffset = 13
72
   *
96
   *
73
   * src is used for FindFirst/FindNext iterations, then buff1 is filled with
97
   * src is used for FindFirst/FindNext iterations, then buff1 is filled with
74
   * the source filename found by FindFirst/FindNext and buff2 is filled with
98
   * the source filename found by FindFirst/FindNext and buff2 is filled with
75
   * the destination file (with ?'s replaced by whatever is found at the same
99
   * the destination file (with ?'s replaced by whatever is found at the same
76
   * location in buff1).
100
   * location in buff1).
77
   */
101
   */
78
 
102
 
79
  i = findfirst(dta, src, 0);
103
  i = findfirst(dta, src, 0);
80
  if (i != 0) outputnl(doserr(i));
104
  if (i != 0) outputnl(doserr(i));
81
 
105
 
82
  while (i == 0) {
106
  while (i == 0) {
83
    /* write found fname into buff1 and dst fname into buff2 - both in FCB
107
    /* write found fname into buff1 and dst fname into buff2 - both in FCB
84
     * format (MYFILE  EXT) so it is easy to compare them */
108
     * format (MYFILE  EXT) so it is easy to compare them */
85
    file_fname2fcb(buff1 + fnameoffset, dta->fname);
109
    file_fname2fcb(buff1 + fnameoffset, dta->fname);
86
    file_fname2fcb(buff2 + fnameoffset, dst + fnameoffset);
110
    file_fname2fcb(buff2 + fnameoffset, dst + fnameoffset);
87
 
111
 
88
    /* scan buff2 fname for '?' and replace them with whatever is in buff1 */
112
    /* scan buff2 fname for '?' and replace them with whatever is in buff1 */
89
    for (i = fnameoffset; buff2[i] != 0; i++) {
113
    for (i = fnameoffset; buff2[i] != 0; i++) {
90
      if (buff2[i] == '?') buff2[i] = buff1[i];
114
      if (buff2[i] == '?') buff2[i] = buff1[i];
91
    }
115
    }
92
 
116
 
93
    /* fill buff1 with the 8+3 found file and convert the one in buff2 to 8+3 as well */
117
    /* fill buff1 with the 8+3 found file and convert the one in buff2 to 8+3 as well */
94
    file_fcb2fname(buff1 + fnameoffset, buff2 + fnameoffset);
118
    file_fcb2fname(buff1 + fnameoffset, buff2 + fnameoffset);
95
    strcpy(buff2 + fnameoffset, buff1 + fnameoffset);
119
    strcpy(buff2 + fnameoffset, buff1 + fnameoffset);
96
    strcpy(buff1 + fnameoffset, dta->fname);
120
    strcpy(buff1 + fnameoffset, dta->fname);
97
 
121
 
98
    /* buff1 contains now a fully resolved source and buff2 a proper destination */
122
    /* buff1 contains now a fully resolved source and buff2 a proper destination */
99
    #if 0  /* DEBUG ("if 1" to enable) */
123
    #if 0  /* DEBUG ("if 1" to enable) */
100
    output(buff1);
124
    output(buff1);
101
    output(" -> ");
125
    output(" -> ");
102
    outputnl(buff2);
126
    outputnl(buff2);
103
    #endif
127
    #endif
104
    /* call DOS to do the actual job */
128
    /* call DOS to do the actual job */
105
    i = 0;
129
    i = 0;
106
    _asm {
130
    _asm {
107
      push ax
131
      push ax
108
      push di
132
      push di
109
      push dx
133
      push dx
110
      push es
134
      push es
111
 
135
 
112
      mov ah, 0x56  /* rename file: DS:DX=ASCIIZ of src  ES:DI=ASCIIZ of dst */
136
      mov ah, 0x56  /* rename file: DS:DX=ASCIIZ of src  ES:DI=ASCIIZ of dst */
113
      push ds
137
      push ds
114
      pop es
138
      pop es
115
      mov dx, buff1
139
      mov dx, buff1
116
      mov di, buff2
140
      mov di, buff2
117
      int 0x21      /* CF clear on success, otherwise err code in AX */
141
      int 0x21      /* CF clear on success, otherwise err code in AX */
118
      jnc DONE
142
      jnc DONE
119
      mov [i], ax   /* copy error code to i */
143
      mov [i], ax   /* copy error code to i */
120
      DONE:
144
      DONE:
121
 
145
 
122
      pop es
146
      pop es
123
      pop dx
147
      pop dx
124
      pop di
148
      pop di
125
      pop ax
149
      pop ax
126
    }
150
    }
127
    if (i != 0) {
151
    if (i != 0) {
128
      output(buff1 + fnameoffset);
152
      output(buff1 + fnameoffset);
129
      output(" -> ");
153
      output(" -> ");
130
      output(buff2 + fnameoffset);
154
      output(buff2 + fnameoffset);
131
      output("  ");
155
      output("  ");
132
      outputnl(doserr(i));
156
      outputnl(doserr(i));
133
    }
157
    }
134
    /* next please */
158
    /* next please */
135
    i = findnext(dta);
159
    i = findnext(dta);
136
  }
160
  }
137
 
161
 
138
  return(-1);
162
  return(-1);
139
}
163
}
140
 
164