Subversion Repositories SvarDOS

Rev

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

Rev 431 Rev 501
1
/* This file is part of the SvarCOM project and is published under the terms
1
/* This file is part of the SvarCOM project and is published under the terms
2
 * of the MIT license.
2
 * of the MIT license.
3
 *
3
 *
4
 * Copyright (C) 2021 Mateusz Viste
4
 * Copyright (C) 2021 Mateusz Viste
5
 *
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
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
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:
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
12
 *
13
 * The above copyright notice and this permission notice shall be included in
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
14
 * all copies or substantial portions of the Software.
15
 *
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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,
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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
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
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
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
22
 * DEALINGS IN THE SOFTWARE.
23
 */
23
 */
24
 
24
 
25
/*
25
/*
26
 * date [date]
26
 * date [date]
27
 */
27
 */
28
 
28
 
29
 
29
 
30
/* parse a NULL-terminated string int hour, minutes and seconds, returns 0 on success
30
/* parse a NULL-terminated string int hour, minutes and seconds, returns 0 on success
31
 * valid inputs: 0, 7, 5:5, 23:23, 17:54:45, 9p, 9:05, ...
31
 * valid inputs: 0, 7, 5:5, 23:23, 17:54:45, 9p, 9:05, ...
32
 */
32
 */
33
static int cmd_date_parse(const char *s, unsigned short *year, unsigned char *mo, unsigned char *dy, struct nls_patterns *nls) {
33
static int cmd_date_parse(const char *s, unsigned short *year, unsigned char *mo, unsigned char *dy, struct nls_patterns *nls) {
34
  unsigned short i;
34
  unsigned short i;
35
  const char *ptrs[2] = {NULL, NULL};
35
  const char *ptrs[2] = {NULL, NULL};
36
 
36
 
37
  *year = 0;
37
  *year = 0;
38
  *mo = 0;
38
  *mo = 0;
39
  *dy = 0;
39
  *dy = 0;
40
 
40
 
41
  /* validate input - must contain only chars 0-9 and time separator */
41
  /* validate input - must contain only chars 0-9 and time separator */
42
  for (i = 0; s[i] != 0; i++) {
42
  for (i = 0; s[i] != 0; i++) {
43
    switch (s[i]) {
43
    switch (s[i]) {
44
      case '0':
44
      case '0':
45
      case '1':
45
      case '1':
46
      case '2':
46
      case '2':
47
      case '3':
47
      case '3':
48
      case '4':
48
      case '4':
49
      case '5':
49
      case '5':
50
      case '6':
50
      case '6':
51
      case '7':
51
      case '7':
52
      case '8':
52
      case '8':
53
      case '9':
53
      case '9':
54
        break;
54
        break;
55
      default:
55
      default:
56
        if ((s[i] != nls->datesep[0]) || (i == 0)) return(-1);
56
        if ((s[i] != nls->datesep[0]) || (i == 0)) return(-1);
57
        if (ptrs[0] == NULL) {
57
        if (ptrs[0] == NULL) {
58
          ptrs[0] = s + i + 1;
58
          ptrs[0] = s + i + 1;
59
        } else if (ptrs[1] == NULL) {
59
        } else if (ptrs[1] == NULL) {
60
          ptrs[1] = s + i + 1;
60
          ptrs[1] = s + i + 1;
61
        } else { /* too many separators */
61
        } else { /* too many separators */
62
          return(-1);
62
          return(-1);
63
        }
63
        }
64
        break;
64
        break;
65
    }
65
    }
66
  }
66
  }
67
 
67
 
68
  /* did I get all separators? */
68
  /* did I get all separators? */
69
  if ((ptrs[0] == NULL) || (ptrs[1] == NULL)) goto FAIL;
69
  if ((ptrs[0] == NULL) || (ptrs[1] == NULL)) goto FAIL;
70
 
70
 
71
  /* d/m/y order depends on NLS settings */
71
  /* d/m/y order depends on NLS settings */
72
  switch (nls->dateformat) {
72
  switch (nls->dateformat) {
73
    case 0:  /* m/d/y */
73
    case 0:  /* m/d/y */
74
      atous(&i, s);
74
      atous(&i, s);
75
      *mo = i;
75
      *mo = i;
76
      atous(&i, ptrs[0]);
76
      atous(&i, ptrs[0]);
77
      *dy = i;
77
      *dy = i;
78
      atous(year, ptrs[1]);
78
      atous(year, ptrs[1]);
79
      break;
79
      break;
80
    case 1:  /* d/m/y */
80
    case 1:  /* d/m/y */
81
      atous(&i, s);
81
      atous(&i, s);
82
      *dy = i;
82
      *dy = i;
83
      atous(&i, ptrs[0]);
83
      atous(&i, ptrs[0]);
84
      *mo = i;
84
      *mo = i;
85
      atous(year, ptrs[1]);
85
      atous(year, ptrs[1]);
86
      break;
86
      break;
87
    default: /* y/m/d */
87
    default: /* y/m/d */
88
      atous(year, s);
88
      atous(year, s);
89
      atous(&i, ptrs[0]);
89
      atous(&i, ptrs[0]);
90
      *mo = i;
90
      *mo = i;
91
      atous(&i, ptrs[1]);
91
      atous(&i, ptrs[1]);
92
      *dy = i;
92
      *dy = i;
93
      break;
93
      break;
94
  }
94
  }
95
 
95
 
96
  return(0);
96
  return(0);
97
 
97
 
98
  FAIL:
98
  FAIL:
99
  *year = 0;
99
  *year = 0;
100
  return(-1);
100
  return(-1);
101
}
101
}
102
 
102
 
103
 
103
 
104
/* set system date, return 0 on success */
104
/* set system date, return 0 on success */
105
static int cmd_date_set(unsigned short year, unsigned char mo, unsigned char dy) {
105
static int cmd_date_set(unsigned short year, unsigned char mo, unsigned char dy) {
106
  _asm {
106
  _asm {
107
    push ax
107
    push ax
108
    push bx
108
    push bx
109
    push cx
109
    push cx
110
    push dx
110
    push dx
111
 
111
 
112
    mov ax, 0x2b00 /* DOS 1+ -- Set DOS Date */
112
    mov ax, 0x2b00 /* DOS 1+ -- Set DOS Date */
113
    mov cx, [year] /* year (1980-2099) */
113
    mov cx, [year] /* year (1980-2099) */
114
    mov dh, [mo]   /* month (1-12) */
114
    mov dh, [mo]   /* month (1-12) */
115
    mov dl, [dy]   /* day (1-31) */
115
    mov dl, [dy]   /* day (1-31) */
116
    int 0x21       /* AL = 0 on success */
116
    int 0x21       /* AL = 0 on success */
117
    cmp al, 0
117
    cmp al, 0
118
    je DONE
118
    je DONE
119
    mov [year], 0
119
    mov [year], 0
120
    DONE:
120
    DONE:
121
 
121
 
122
    pop dx
122
    pop dx
123
    pop cx
123
    pop cx
124
    pop bx
124
    pop bx
125
    pop ax
125
    pop ax
126
  }
126
  }
127
 
127
 
128
  if (year == 0) return(-1);
128
  if (year == 0) return(-1);
129
  return(0);
129
  return(0);
130
}
130
}
131
 
131
 
132
 
132
 
133
static int cmd_date(struct cmd_funcparam *p) {
133
static int cmd_date(struct cmd_funcparam *p) {
134
  struct nls_patterns *nls = (void *)(p->BUFFER);
134
  struct nls_patterns *nls = (void *)(p->BUFFER);
135
  char *buff = p->BUFFER + (BUFFER_SIZE / 2);
135
  char *buff = p->BUFFER + sizeof(*nls);
136
  unsigned short i;
136
  unsigned short i;
137
  unsigned short year = 0;
137
  unsigned short year = 0;
138
  unsigned char mo, dy;
138
  unsigned char mo, dy;
139
 
139
 
140
  if (cmd_ishlp(p)) {
140
  if (cmd_ishlp(p)) {
141
    outputnl("Displays or sets the system date.");
141
    outputnl("Displays or sets the system date.");
142
    outputnl("");
142
    outputnl("");
143
    outputnl("DATE [date]");
143
    outputnl("DATE [date]");
144
    outputnl("");
144
    outputnl("");
145
    outputnl("Type DATE with no parameters to display the current date and a prompt for a");
145
    outputnl("Type DATE with no parameters to display the current date and a prompt for a");
146
    outputnl("new one. Press ENTER to keep the same date.");
146
    outputnl("new one. Press ENTER to keep the same date.");
147
    return(-1);
147
    return(-1);
148
  }
148
  }
149
 
149
 
150
  i = nls_getpatterns(nls);
150
  i = nls_getpatterns(nls);
151
  if (i != 0) {
151
  if (i != 0) {
152
    outputnl(doserr(i));
152
    outputnl(doserr(i));
153
    return(-1);
153
    return(-1);
154
  }
154
  }
155
 
155
 
156
  /* display current date if no args */
156
  /* display current date if no args */
157
  if (p->argc == 0) {
157
  if (p->argc == 0) {
158
    /* get cur date */
158
    /* get cur date */
159
    _asm {
159
    _asm {
160
      push ax
160
      push ax
161
      push cx
161
      push cx
162
      push dx
162
      push dx
163
 
163
 
164
      mov ah, 0x2a  /* DOS 1+ -- Query DOS Date */
164
      mov ah, 0x2a  /* DOS 1+ -- Query DOS Date */
165
      int 0x21      /* CX=year DH=month DL=day */
165
      int 0x21      /* CX=year DH=month DL=day */
166
      mov [year], cx
166
      mov [year], cx
167
      mov [mo], dh
167
      mov [mo], dh
168
      mov [dy], dl
168
      mov [dy], dl
169
 
169
 
170
      pop dx
170
      pop dx
171
      pop cx
171
      pop cx
172
      pop ax
172
      pop ax
173
    }
173
    }
174
    buff[0] = ' ';
174
    buff[0] = ' ';
175
    nls_format_date(buff + 1, year, mo, dy, nls);
175
    nls_format_date(buff + 1, year, mo, dy, nls);
176
    output("Current date is");
176
    output("Current date is");
177
    outputnl(buff);
177
    outputnl(buff);
178
    year = 0;
178
    year = 0;
179
  } else { /* parse date if provided */
179
  } else { /* parse date if provided */
180
    if ((cmd_date_parse(p->argv[0], &year, &mo, &dy, nls) != 0) || (cmd_date_set(year, mo, dy) != 0)) {
180
    if ((cmd_date_parse(p->argv[0], &year, &mo, &dy, nls) != 0) || (cmd_date_set(year, mo, dy) != 0)) {
181
      outputnl("Invalid date");
181
      outputnl("Invalid date");
182
      year = 0;
182
      year = 0;
183
    }
183
    }
184
  }
184
  }
185
 
185
 
186
  /* ask for date if not provided or if input was malformed */
186
  /* ask for date if not provided or if input was malformed */
187
  while (year == 0) {
187
  while (year == 0) {
188
    output("Enter new date:");
188
    output("Enter new date:");
189
    output(" ");
189
    output(" ");
190
    /* collect user input into buff */
190
    /* collect user input into buff */
191
    _asm {
191
    _asm {
192
      push ax
192
      push ax
193
      push bx
193
      push bx
194
      push dx
194
      push dx
195
 
195
 
196
      mov ah, 0x0a   /* DOS 1+ -- Buffered String Input */
196
      mov ah, 0x0a   /* DOS 1+ -- Buffered String Input */
197
      mov bx, buff
197
      mov bx, buff
198
      mov dx, bx
198
      mov dx, bx
199
      mov al, 16
199
      mov al, 16
200
      mov [bx], al   /* max input length */
200
      mov [bx], al   /* max input length */
201
      mov al, 1
201
      mov al, 1
202
      mov [bx+1], al /* zero out the "previous entry" length */
202
      mov [bx+1], al /* zero out the "previous entry" length */
203
      int 0x21
203
      int 0x21
204
      /* terminate the string with a NULL terminator */
204
      /* terminate the string with a NULL terminator */
205
      xor ax, ax
205
      xor ax, ax
206
      inc bx
206
      inc bx
207
      mov al, [bx] /* read length of input string */
207
      mov al, [bx] /* read length of input string */
208
      mov bx, ax
208
      mov bx, ax
209
      add bx, dx
209
      add bx, dx
210
      mov [bx+2], ah
210
      mov [bx+2], ah
211
      /* output a \n */
211
      /* output a \n */
212
      mov ah, 2
212
      mov ah, 2
213
      mov dl, 0x0A
213
      mov dl, 0x0A
214
      int 0x21
214
      int 0x21
215
 
215
 
216
      pop dx
216
      pop dx
217
      pop bx
217
      pop bx
218
      pop ax
218
      pop ax
219
    }
219
    }
220
    if (buff[1] == 0) break; /* empty string = no date change */
220
    if (buff[1] == 0) break; /* empty string = no date change */
221
    if ((cmd_date_parse(buff + 2, &year, &mo, &dy, nls) == 0) && (cmd_date_set(year, mo, dy) == 0)) break;
221
    if ((cmd_date_parse(buff + 2, &year, &mo, &dy, nls) == 0) && (cmd_date_set(year, mo, dy) == 0)) break;
222
    outputnl("Invalid date");
222
    outputnl("Invalid date");
223
  }
223
  }
224
 
224
 
225
  return(-1);
225
  return(-1);
226
}
226
}
227
 
227