Subversion Repositories SvarDOS

Rev

Rev 989 | 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
 *
1823 mateusz.vi 4
 * Copyright (C) 2021-2024 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 */
1823 mateusz.vi 158
    dos_get_date(&year, &mo, &dy);
431 mateuszvis 159
 
160
    buff[0] = ' ';
161
    nls_format_date(buff + 1, year, mo, dy, nls);
989 mateusz.vi 162
    nls_output(32,4); /* "Current date is" */
431 mateuszvis 163
    outputnl(buff);
164
    year = 0;
165
  } else { /* parse date if provided */
166
    if ((cmd_date_parse(p->argv[0], &year, &mo, &dy, nls) != 0) || (cmd_date_set(year, mo, dy) != 0)) {
989 mateusz.vi 167
      nls_outputnl(32,3); /* "Invalid date" */
431 mateuszvis 168
      year = 0;
169
    }
170
  }
171
 
172
  /* ask for date if not provided or if input was malformed */
173
  while (year == 0) {
989 mateusz.vi 174
    nls_output(32,5); /* "Enter new date:" */
431 mateuszvis 175
    output(" ");
176
    /* collect user input into buff */
177
    _asm {
178
      push ax
179
      push bx
180
      push dx
181
 
182
      mov ah, 0x0a   /* DOS 1+ -- Buffered String Input */
183
      mov bx, buff
184
      mov dx, bx
185
      mov al, 16
186
      mov [bx], al   /* max input length */
187
      mov al, 1
188
      mov [bx+1], al /* zero out the "previous entry" length */
189
      int 0x21
190
      /* terminate the string with a NULL terminator */
191
      xor ax, ax
192
      inc bx
193
      mov al, [bx] /* read length of input string */
194
      mov bx, ax
195
      add bx, dx
196
      mov [bx+2], ah
197
      /* output a \n */
198
      mov ah, 2
199
      mov dl, 0x0A
200
      int 0x21
201
 
202
      pop dx
203
      pop bx
204
      pop ax
205
    }
206
    if (buff[1] == 0) break; /* empty string = no date change */
207
    if ((cmd_date_parse(buff + 2, &year, &mo, &dy, nls) == 0) && (cmd_date_set(year, mo, dy) == 0)) break;
989 mateusz.vi 208
    nls_outputnl(32,3); /* "Invalid date" */
431 mateuszvis 209
  }
210
 
533 mateuszvis 211
  return(CMD_OK);
431 mateuszvis 212
}