2 * Copyright (c) 2012 Maurizio Lombardi
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <device/clock_dev.h>
41 static errno_t
read_date_from_arg(char *wdate
, struct tm
*t
);
42 static errno_t
read_time_from_arg(char *wdate
, struct tm
*t
);
43 static errno_t
tm_sanity_check(struct tm
*t
);
44 static bool is_leap_year(int year
);
46 static void usage(void);
48 static int days_month
[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
51 main(int argc
, char **argv
)
57 service_id_t
*svc_ids
= NULL
;
59 char *svc_name
= NULL
;
60 bool read_only
= true;
66 while ((c
= getopt(argc
, argv
, "hd:t:")) != -1) {
76 wdate
= (char *)optarg
;
85 wtime
= (char *)optarg
;
96 printf(NAME
": Unrecognized parameter\n");
101 /* Get the id of the clock category */
102 rc
= loc_category_get_id("clock", &cat_id
, IPC_FLAG_BLOCKING
);
104 printf(NAME
": Cannot get clock category id\n");
108 /* Get the list of available services in the clock category */
109 rc
= loc_category_get_svcs(cat_id
, &svc_ids
, &svc_cnt
);
111 printf(NAME
": Cannot get the list of services in the clock "
116 /* Check if there are available services in the clock category */
118 printf(NAME
": No available service found in "
119 "the clock category\n");
123 /* Get the name of the clock service */
124 rc
= loc_service_get_name(svc_ids
[0], &svc_name
);
126 printf(NAME
": Cannot get the name of the service\n");
130 /* Get the service id for the device */
131 rc
= loc_service_get_id(svc_name
, &svc_id
, 0);
133 printf(NAME
": Cannot get the service id for device %s",
138 /* Connect to the device */
139 async_sess_t
*sess
= loc_service_connect(svc_id
, INTERFACE_DDF
, 0);
141 printf(NAME
": Cannot connect to the device\n");
145 /* Read the current date/time */
146 rc
= clock_dev_time_get(sess
, &t
);
148 printf(NAME
": Cannot read the current time\n");
153 /* Print the current time and exit */
154 printf("%02d/%02d/%d ", t
.tm_mday
,
155 t
.tm_mon
+ 1, 1900 + t
.tm_year
);
156 printf("%02d:%02d:%02d\n", t
.tm_hour
, t
.tm_min
, t
.tm_sec
);
159 rc
= read_date_from_arg(wdate
, &t
);
161 printf(NAME
": error, date format not "
168 rc
= read_time_from_arg(wtime
, &t
);
170 printf(NAME
": error, time format not "
177 rc
= tm_sanity_check(&t
);
179 printf(NAME
": error, invalid date/time\n");
183 rc
= clock_dev_time_set(sess
, &t
);
185 printf(NAME
": error, Unable to set date/time\n");
196 /** Read the day, month and year from a string
197 * with the following format: DD/MM/YYYY
200 read_date_from_arg(char *wdate
, struct tm
*t
)
205 if (str_size(wdate
) != 10) /* str_size("DD/MM/YYYY") == 10 */
208 if (wdate
[2] != '/' ||
213 rc
= str_uint32_t(&wdate
[0], NULL
, 10, false, &tmp
);
219 rc
= str_uint32_t(&wdate
[3], NULL
, 10, false, &tmp
);
225 rc
= str_uint32_t(&wdate
[6], NULL
, 10, false, &tmp
);
226 t
->tm_year
= tmp
- 1900;
231 /** Read the hours, minutes and seconds from a string
232 * with the following format: HH:MM:SS or HH:MM
235 read_time_from_arg(char *wtime
, struct tm
*t
)
238 size_t len
= str_size(wtime
);
239 bool sec_present
= len
== 8;
242 /* str_size("HH:MM") == 5 */
243 /* str_size("HH:MM:SS") == 8 */
244 if (len
!= 8 && len
!= 5)
247 if (sec_present
&& wtime
[5] != ':')
253 rc
= str_uint32_t(&wtime
[0], NULL
, 10, false, &tmp
);
259 rc
= str_uint32_t(&wtime
[3], NULL
, 10, false, &tmp
);
266 rc
= str_uint32_t(&wtime
[6], NULL
, 10, false, &tmp
);
274 /** Check if the tm structure contains valid values
276 * @param t The tm structure to check
278 * @return EOK on success or EINVAL
281 tm_sanity_check(struct tm
*t
)
285 if (t
->tm_sec
< 0 || t
->tm_sec
> 59)
287 else if (t
->tm_min
< 0 || t
->tm_min
> 59)
289 else if (t
->tm_hour
< 0 || t
->tm_hour
> 23)
291 else if (t
->tm_mday
< 1 || t
->tm_mday
> 31)
293 else if (t
->tm_mon
< 0 || t
->tm_mon
> 11)
295 else if (t
->tm_year
< 0 || t
->tm_year
> 199)
298 if (t
->tm_mon
== 1/* FEB */ && is_leap_year(t
->tm_year
))
301 ndays
= days_month
[t
->tm_mon
];
303 if (t
->tm_mday
> ndays
)
309 /** Check if a year is a leap year
311 * @param year The year to check
313 * @return true if it is a leap year, false otherwise
316 is_leap_year(int year
)
333 printf("Usage: date [-d DD/MM/YYYY] [-t HH:MM[:SS]]\n");
334 printf(" -d Change the current date\n");
335 printf(" -t Change the current time\n");
336 printf(" -h Display this information\n");