Subversion Repositories SvarDOS

Rev

Rev 538 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 mateuszvis 1
/* This file is part of the SvarCOM project and is published under the terms
2
 * of the MIT license.
3
 *
989 mateusz.vi 4
 * Copyright (C) 2021-2022 Mateusz Viste
431 mateuszvis 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
 
25
/*
26
 * date [date]
27
 */
28
 
29
 
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, ...
32
 */
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;
35
  const char *ptrs[2] = {NULL, NULL};
36
 
37
  *year = 0;
38
  *mo = 0;
39
  *dy = 0;
40
 
41
  /* validate input - must contain only chars 0-9 and time separator */
42
  for (i = 0; s[i] != 0; i++) {
43
    switch (s[i]) {
44
      case '0':
45
      case '1':
46
      case '2':
47
      case '3':
48
      case '4':
49
      case '5':
50
      case '6':
51
      case '7':
52
      case '8':
53
      case '9':
54
        break;
55
      default:
56
        if ((s[i] != nls->datesep[0]) || (i == 0)) return(-1);
57
        if (ptrs[0] == NULL) {
58
          ptrs[0] = s + i + 1;
59
        } else if (ptrs[1] == NULL) {
60
          ptrs[1] = s + i + 1;
61
        } else { /* too many separators */
62
          return(-1);
63
        }
64
        break;
65
    }
66
  }
67
 
68
  /* did I get all separators? */
69
  if ((ptrs[0] == NULL) || (ptrs[1] == NULL)) goto FAIL;
70
 
71
  /* d/m/y order depends on NLS settings */
72
  switch (nls->dateformat) {
73
    case 0:  /* m/d/y */
74
      atous(&i, s);
75
      *mo = i;
76
      atous(&i, ptrs[0]);
77
      *dy = i;
78
      atous(year, ptrs[1]);
79
      break;
80
    case 1:  /* d/m/y */
81
      atous(&i, s);
82
      *dy = i;
83
      atous(&i, ptrs[0]);
84
      *mo = i;
85
      atous(year, ptrs[1]);
86
      break;
87
    default: /* y/m/d */
88
      atous(year, s);
89
      atous(&i, ptrs[0]);
90
      *mo = i;
91
      atous(&i, ptrs[1]);
92
      *dy = i;
93
      break;
94
  }
95
 
96
  return(0);
97
 
98
  FAIL:
99
  *year = 0;
100
  return(-1);
101
}
102
 
103
 
104
/* set system date, return 0 on success */
105
static int cmd_date_set(unsigned short year, unsigned char mo, unsigned char dy) {
106
  _asm {
107
    push ax
108
    push bx
109
    push cx
110
    push dx
111
 
112
    mov ax, 0x2b00 /* DOS 1+ -- Set DOS Date */
113
    mov cx, [year] /* year (1980-2099) */
114
    mov dh, [mo]   /* month (1-12) */
115
    mov dl, [dy]   /* day (1-31) */
116
    int 0x21       /* AL = 0 on success */
117
    cmp al, 0
118
    je DONE
119
    mov [year], 0
120
    DONE:
121
 
122
    pop dx
123
    pop cx
124
    pop bx
125
    pop ax
126
  }
127
 
128
  if (year == 0) return(-1);
129
  return(0);
130
}
131
 
132
 
533 mateuszvis 133
static enum cmd_result cmd_date(struct cmd_funcparam *p) {
431 mateuszvis 134
  struct nls_patterns *nls = (void *)(p->BUFFER);
501 mateuszvis 135
  char *buff = p->BUFFER + sizeof(*nls);
431 mateuszvis 136
  unsigned short i;
137
  unsigned short year = 0;
138
  unsigned char mo, dy;
139
 
140
  if (cmd_ishlp(p)) {
989 mateusz.vi 141
    nls_outputnl(32,0); /* "Displays or sets the system date."); */
431 mateuszvis 142
    outputnl("");
989 mateusz.vi 143
    nls_outputnl(32,1); /* "DATE [date]" */
431 mateuszvis 144
    outputnl("");
989 mateusz.vi 145
    nls_outputnl(32,2); /* "Type DATE with no parameters to display the (...)" */
533 mateuszvis 146
    return(CMD_OK);
431 mateuszvis 147
  }
148
 
149
  i = nls_getpatterns(nls);
150
  if (i != 0) {
538 mateuszvis 151
    nls_outputnl_doserr(i);
533 mateuszvis 152
    return(CMD_FAIL);
431 mateuszvis 153
  }
154
 
155
  /* display current date if no args */
156
  if (p->argc == 0) {
157
    /* get cur date */
158
    _asm {
159
      push ax
160
      push cx
161
      push dx
162
 
163
      mov ah, 0x2a  /* DOS 1+ -- Query DOS Date */
164
      int 0x21      /* CX=year DH=month DL=day */
165
      mov [year], cx
166
      mov [mo], dh
167
      mov [dy], dl
168
 
169
      pop dx
170
      pop cx
171
      pop ax
172
    }
173
    buff[0] = ' ';
174
    nls_format_date(buff + 1, year, mo, dy, nls);
989 mateusz.vi 175
    nls_output(32,4); /* "Current date is" */
431 mateuszvis 176
    outputnl(buff);
177
    year = 0;
178
  } else { /* parse date if provided */
179
    if ((cmd_date_parse(p->argv[0], &year, &mo, &dy, nls) != 0) || (cmd_date_set(year, mo, dy) != 0)) {
989 mateusz.vi 180
      nls_outputnl(32,3); /* "Invalid date" */
431 mateuszvis 181
      year = 0;
182
    }
183
  }
184
 
185
  /* ask for date if not provided or if input was malformed */
186
  while (year == 0) {
989 mateusz.vi 187
    nls_output(32,5); /* "Enter new date:" */
431 mateuszvis 188
    output(" ");
189
    /* collect user input into buff */
190
    _asm {
191
      push ax
192
      push bx
193
      push dx
194
 
195
      mov ah, 0x0a   /* DOS 1+ -- Buffered String Input */
196
      mov bx, buff
197
      mov dx, bx
198
      mov al, 16
199
      mov [bx], al   /* max input length */
200
      mov al, 1
201
      mov [bx+1], al /* zero out the "previous entry" length */
202
      int 0x21
203
      /* terminate the string with a NULL terminator */
204
      xor ax, ax
205
      inc bx
206
      mov al, [bx] /* read length of input string */
207
      mov bx, ax
208
      add bx, dx
209
      mov [bx+2], ah
210
      /* output a \n */
211
      mov ah, 2
212
      mov dl, 0x0A
213
      int 0x21
214
 
215
      pop dx
216
      pop bx
217
      pop ax
218
    }
219
    if (buff[1] == 0) break; /* empty string = no date change */
220
    if ((cmd_date_parse(buff + 2, &year, &mo, &dy, nls) == 0) && (cmd_date_set(year, mo, dy) == 0)) break;
989 mateusz.vi 221
    nls_outputnl(32,3); /* "Invalid date" */
431 mateuszvis 222
  }
223
 
533 mateuszvis 224
  return(CMD_OK);
431 mateuszvis 225
}