Subversion Repositories SvarDOS

Rev

Rev 538 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 538 Rev 989
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-2022 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 enum cmd_result cmd_date(struct cmd_funcparam *p) {
133
static enum cmd_result 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 + sizeof(*nls);
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
    nls_outputnl(32,0); /* "Displays or sets the system date."); */
142
    outputnl("");
142
    outputnl("");
143
    outputnl("DATE [date]");
143
    nls_outputnl(32,1); /* "DATE [date]" */
144
    outputnl("");
144
    outputnl("");
145
    outputnl("Type DATE with no parameters to display the current date and a prompt for a");
145
    nls_outputnl(32,2); /* "Type DATE with no parameters to display the (...)" */
146
    outputnl("new one. Press ENTER to keep the same date.");
-
 
147
    return(CMD_OK);
146
    return(CMD_OK);
148
  }
147
  }
149
 
148
 
150
  i = nls_getpatterns(nls);
149
  i = nls_getpatterns(nls);
151
  if (i != 0) {
150
  if (i != 0) {
152
    nls_outputnl_doserr(i);
151
    nls_outputnl_doserr(i);
153
    return(CMD_FAIL);
152
    return(CMD_FAIL);
154
  }
153
  }
155
 
154
 
156
  /* display current date if no args */
155
  /* display current date if no args */
157
  if (p->argc == 0) {
156
  if (p->argc == 0) {
158
    /* get cur date */
157
    /* get cur date */
159
    _asm {
158
    _asm {
160
      push ax
159
      push ax
161
      push cx
160
      push cx
162
      push dx
161
      push dx
163
 
162
 
164
      mov ah, 0x2a  /* DOS 1+ -- Query DOS Date */
163
      mov ah, 0x2a  /* DOS 1+ -- Query DOS Date */
165
      int 0x21      /* CX=year DH=month DL=day */
164
      int 0x21      /* CX=year DH=month DL=day */
166
      mov [year], cx
165
      mov [year], cx
167
      mov [mo], dh
166
      mov [mo], dh
168
      mov [dy], dl
167
      mov [dy], dl
169
 
168
 
170
      pop dx
169
      pop dx
171
      pop cx
170
      pop cx
172
      pop ax
171
      pop ax
173
    }
172
    }
174
    buff[0] = ' ';
173
    buff[0] = ' ';
175
    nls_format_date(buff + 1, year, mo, dy, nls);
174
    nls_format_date(buff + 1, year, mo, dy, nls);
176
    output("Current date is");
175
    nls_output(32,4); /* "Current date is" */
177
    outputnl(buff);
176
    outputnl(buff);
178
    year = 0;
177
    year = 0;
179
  } else { /* parse date if provided */
178
  } 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)) {
179
    if ((cmd_date_parse(p->argv[0], &year, &mo, &dy, nls) != 0) || (cmd_date_set(year, mo, dy) != 0)) {
181
      outputnl("Invalid date");
180
      nls_outputnl(32,3); /* "Invalid date" */
182
      year = 0;
181
      year = 0;
183
    }
182
    }
184
  }
183
  }
185
 
184
 
186
  /* ask for date if not provided or if input was malformed */
185
  /* ask for date if not provided or if input was malformed */
187
  while (year == 0) {
186
  while (year == 0) {
188
    output("Enter new date:");
187
    nls_output(32,5); /* "Enter new date:" */
189
    output(" ");
188
    output(" ");
190
    /* collect user input into buff */
189
    /* collect user input into buff */
191
    _asm {
190
    _asm {
192
      push ax
191
      push ax
193
      push bx
192
      push bx
194
      push dx
193
      push dx
195
 
194
 
196
      mov ah, 0x0a   /* DOS 1+ -- Buffered String Input */
195
      mov ah, 0x0a   /* DOS 1+ -- Buffered String Input */
197
      mov bx, buff
196
      mov bx, buff
198
      mov dx, bx
197
      mov dx, bx
199
      mov al, 16
198
      mov al, 16
200
      mov [bx], al   /* max input length */
199
      mov [bx], al   /* max input length */
201
      mov al, 1
200
      mov al, 1
202
      mov [bx+1], al /* zero out the "previous entry" length */
201
      mov [bx+1], al /* zero out the "previous entry" length */
203
      int 0x21
202
      int 0x21
204
      /* terminate the string with a NULL terminator */
203
      /* terminate the string with a NULL terminator */
205
      xor ax, ax
204
      xor ax, ax
206
      inc bx
205
      inc bx
207
      mov al, [bx] /* read length of input string */
206
      mov al, [bx] /* read length of input string */
208
      mov bx, ax
207
      mov bx, ax
209
      add bx, dx
208
      add bx, dx
210
      mov [bx+2], ah
209
      mov [bx+2], ah
211
      /* output a \n */
210
      /* output a \n */
212
      mov ah, 2
211
      mov ah, 2
213
      mov dl, 0x0A
212
      mov dl, 0x0A
214
      int 0x21
213
      int 0x21
215
 
214
 
216
      pop dx
215
      pop dx
217
      pop bx
216
      pop bx
218
      pop ax
217
      pop ax
219
    }
218
    }
220
    if (buff[1] == 0) break; /* empty string = no date change */
219
    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;
220
    if ((cmd_date_parse(buff + 2, &year, &mo, &dy, nls) == 0) && (cmd_date_set(year, mo, dy) == 0)) break;
222
    outputnl("Invalid date");
221
    nls_outputnl(32,3); /* "Invalid date" */
223
  }
222
  }
224
 
223
 
225
  return(CMD_OK);
224
  return(CMD_OK);
226
}
225
}
227
 
226