File azan.c changed (mode: 100644) (index 3160ed5..753baf6) |
4 |
4 |
* print next prayer left duration or today's all prayers. |
* print next prayer left duration or today's all prayers. |
5 |
5 |
*/ |
*/ |
6 |
6 |
|
|
7 |
|
#include <time.h> |
|
|
7 |
|
#include <math.h> |
8 |
8 |
#include <stdio.h> |
#include <stdio.h> |
9 |
9 |
#include <stdlib.h> |
#include <stdlib.h> |
10 |
|
#include <math.h> |
|
11 |
10 |
#include <string.h> |
#include <string.h> |
12 |
|
#include <getopt.h> |
|
13 |
|
#if defined (__linux__) || (__OpenBSD__) |
|
14 |
|
#include <unistd.h> |
|
15 |
|
#include <sys/types.h> |
|
16 |
11 |
#include <sys/stat.h> |
#include <sys/stat.h> |
17 |
|
#endif |
|
|
12 |
|
#include <sys/types.h> |
|
13 |
|
#include <time.h> |
|
14 |
|
#include <unistd.h> |
18 |
15 |
|
|
19 |
16 |
#include "config.h" |
#include "config.h" |
20 |
|
|
|
21 |
|
/* macros */ |
|
22 |
|
#define FAIL_IF(EXP, MSG) {if(EXP){printf("%s [LINE %d]\n", MSG, __LINE__);\ |
|
23 |
|
exit(EXIT_FAILURE);}} |
|
|
17 |
|
#include "util.h" |
24 |
18 |
|
|
25 |
19 |
/* function declarations */ |
/* function declarations */ |
26 |
20 |
static void usage(void); |
static void usage(void); |
|
... |
... |
static const double get_maghrib(const double, const double); |
42 |
36 |
static const double get_isha(const double, const double, const double); |
static const double get_isha(const double, const double, const double); |
43 |
37 |
static int file_exist(const char*); |
static int file_exist(const char*); |
44 |
38 |
static int create_cache_file(const time_t, const char*); |
static int create_cache_file(const time_t, const char*); |
45 |
|
static time_t *read_azan_cache_file(const char*); |
|
46 |
|
static int print_next_prayer(const time_t, const char*); |
|
47 |
|
static int print_all_prayers(const char*); |
|
48 |
39 |
static char *get_cache_file_name(const time_t); |
static char *get_cache_file_name(const time_t); |
|
40 |
|
static time_t *read_azan_cache_file(const char*); |
|
41 |
|
static time_t *get_all_prayers(const time_t); |
|
42 |
|
static int print_p(const char, const char); |
49 |
43 |
|
|
50 |
44 |
/* function implementations */ |
/* function implementations */ |
51 |
45 |
static void |
static void |
|
... |
... |
static char |
91 |
85 |
{ |
{ |
92 |
86 |
char *result; |
char *result; |
93 |
87 |
size_t result_size = (size_t)32; |
size_t result_size = (size_t)32; |
94 |
|
result = calloc(result_size, sizeof(char)); |
|
95 |
|
FAIL_IF(result == NULL, "[Error] allocating memory."); |
|
|
88 |
|
result = ecalloc(result_size, sizeof(char)); |
96 |
89 |
struct tm new_time = *localtime(&input_time); |
struct tm new_time = *localtime(&input_time); |
97 |
90 |
(void) snprintf(result, result_size, "%.2d:%.2d", |
(void) snprintf(result, result_size, "%.2d:%.2d", |
98 |
91 |
new_time.tm_hour, new_time.tm_min); |
new_time.tm_hour, new_time.tm_min); |
|
... |
... |
static char |
104 |
97 |
{ |
{ |
105 |
98 |
char *result; |
char *result; |
106 |
99 |
size_t result_size = (size_t)32; |
size_t result_size = (size_t)32; |
107 |
|
result = calloc(result_size, sizeof(char)); |
|
108 |
|
FAIL_IF(result == NULL, "[Error] allocating memory."); |
|
|
100 |
|
result = ecalloc(result_size, sizeof(char)); |
109 |
101 |
int hours,minutes; |
int hours,minutes; |
110 |
102 |
int remaining_seconds; |
int remaining_seconds; |
111 |
103 |
int seconds_in_hour = 60 * 60; |
int seconds_in_hour = 60 * 60; |
|
... |
... |
get_isha(const double duhr, const double maghrib, const double D) |
285 |
277 |
} else if (is_ramadan == 1){ |
} else if (is_ramadan == 1){ |
286 |
278 |
isha = maghrib + 120.0 * one_min; |
isha = maghrib + 120.0 * one_min; |
287 |
279 |
|
|
288 |
|
/* Use isha_angle */ |
|
|
280 |
|
/* Use isha_angle */ |
289 |
281 |
} else { |
} else { |
290 |
282 |
isha = duhr + T(isha_angle, D); |
isha = duhr + T(isha_angle, D); |
291 |
283 |
} |
} |
|
... |
... |
file_exist(const char *filename) |
307 |
299 |
} |
} |
308 |
300 |
|
|
309 |
301 |
static int |
static int |
310 |
|
create_cache_file(const time_t t, const char *full_path) |
|
|
302 |
|
create_cache_file(const time_t current_time, const char *full_path) |
|
303 |
|
{ |
|
304 |
|
/* Create Cache File if doesn't exists'*/ |
|
305 |
|
if (file_exist(full_path) == 0){ |
|
306 |
|
return 0; |
|
307 |
|
} |
|
308 |
|
|
|
309 |
|
time_t *azan_array; |
|
310 |
|
azan_array = get_all_prayers(current_time); |
|
311 |
|
FAIL_IF(azan_array == NULL, "[Error] reading array."); |
|
312 |
|
|
|
313 |
|
/* Create cache file */ |
|
314 |
|
FILE *fpointer; |
|
315 |
|
fpointer = fopen(full_path, "w"); |
|
316 |
|
/* Change permission to read only*/ |
|
317 |
|
/* chmod(full_path, 00400); */ |
|
318 |
|
FAIL_IF(fpointer == NULL, "[Error] opening lp cache file."); |
|
319 |
|
|
|
320 |
|
fprintf(fpointer, "%ld\n%ld\n%ld\n%ld\n%ld\n%ld", |
|
321 |
|
(long)azan_array[0], |
|
322 |
|
(long)azan_array[1], |
|
323 |
|
(long)azan_array[2], |
|
324 |
|
(long)azan_array[3], |
|
325 |
|
(long)azan_array[4], |
|
326 |
|
(long)azan_array[5] |
|
327 |
|
); |
|
328 |
|
|
|
329 |
|
(void)fclose(fpointer); |
|
330 |
|
free(azan_array); |
|
331 |
|
azan_array = NULL; |
|
332 |
|
return 0; |
|
333 |
|
} |
|
334 |
|
|
|
335 |
|
static char |
|
336 |
|
*get_cache_file_name(const time_t t) |
311 |
337 |
{ |
{ |
312 |
338 |
/* Current date time */ |
/* Current date time */ |
313 |
339 |
const struct tm current_date = *localtime(&t); |
const struct tm current_date = *localtime(&t); |
|
... |
... |
create_cache_file(const time_t t, const char *full_path) |
315 |
341 |
const int month = current_date.tm_mon + 1; |
const int month = current_date.tm_mon + 1; |
316 |
342 |
const int year = current_date.tm_year + 1900; |
const int year = current_date.tm_year + 1900; |
317 |
343 |
|
|
318 |
|
/* Create Cache File if doesn't exists'*/ |
|
319 |
|
if (file_exist(full_path) < 0){ |
|
320 |
|
|
|
321 |
|
/* Equation of Time */ |
|
322 |
|
const double julian_date = convert_gregorian_to_julian( |
|
323 |
|
year, month, day); |
|
324 |
|
double D = 0.0; |
|
325 |
|
const double equation_of_time = get_equation_time(julian_date, &D); |
|
326 |
|
|
|
327 |
|
/* Today's Prayers time */ |
|
328 |
|
const double duhr = get_duhr(equation_of_time); |
|
329 |
|
const double fajr = get_fajr(duhr, D); |
|
330 |
|
const double maghrib = get_maghrib(duhr, D); |
|
331 |
|
const double isha = get_isha(duhr, maghrib, D); |
|
332 |
|
const double asr = get_asr(duhr, D); |
|
333 |
|
|
|
334 |
|
/* Convert prayer times to unix timestamp */ |
|
335 |
|
time_t prayer_array[6]; |
|
336 |
|
prayer_array[0] = convert_today_double_to_timet(fajr, day); |
|
337 |
|
prayer_array[1] = convert_today_double_to_timet(duhr, day); |
|
338 |
|
prayer_array[2] = convert_today_double_to_timet(asr, day); |
|
339 |
|
prayer_array[3] = convert_today_double_to_timet(maghrib, day); |
|
340 |
|
prayer_array[4] = convert_today_double_to_timet(isha, day); |
|
341 |
|
prayer_array[5] = convert_today_double_to_timet(fajr, day+1); |
|
342 |
|
|
|
343 |
|
/* Create cache file */ |
|
344 |
|
FILE *fpointer; |
|
345 |
|
fpointer = fopen(full_path, "w"); |
|
346 |
|
/* Change permission to read only*/ |
|
347 |
|
// chmod(full_path, 00400); |
|
348 |
|
FAIL_IF(fpointer == NULL, "[Error] opening lp cache file."); |
|
349 |
|
|
|
350 |
|
fprintf(fpointer, "%ld\n%ld\n%ld\n%ld\n%ld\n%ld", |
|
351 |
|
(long)prayer_array[0], |
|
352 |
|
(long)prayer_array[1], |
|
353 |
|
(long)prayer_array[2], |
|
354 |
|
(long)prayer_array[3], |
|
355 |
|
(long)prayer_array[4], |
|
356 |
|
(long)prayer_array[5] |
|
357 |
|
); |
|
358 |
|
|
|
359 |
|
(void)fclose(fpointer); |
|
360 |
|
} |
|
|
344 |
|
const size_t max_file_name = (size_t)128; |
|
345 |
|
char azan_cache_file[128]; |
361 |
346 |
|
|
362 |
|
return 0; |
|
|
347 |
|
(void)snprintf(azan_cache_file, max_file_name, "azan_%.2i-%.2i-%i.txt", |
|
348 |
|
day, month, year); |
|
349 |
|
|
|
350 |
|
char *full_path = ecalloc(max_file_name, sizeof(char)); |
|
351 |
|
strcpy(full_path, cache_dir); |
|
352 |
|
strcat(full_path, "/"); |
|
353 |
|
strcat(full_path, azan_cache_file); |
|
354 |
|
|
|
355 |
|
return full_path; |
363 |
356 |
} |
} |
364 |
357 |
|
|
365 |
358 |
static time_t |
static time_t |
|
... |
... |
static time_t |
370 |
363 |
|
|
371 |
364 |
time_t *pray_times_array; /* the returned array */ |
time_t *pray_times_array; /* the returned array */ |
372 |
365 |
size_t pray_times_array_size = (size_t)6; |
size_t pray_times_array_size = (size_t)6; |
373 |
|
pray_times_array = calloc(pray_times_array_size, sizeof(time_t)); |
|
374 |
|
FAIL_IF(pray_times_array == NULL, "[Error] allocating memory."); |
|
|
366 |
|
pray_times_array = ecalloc(pray_times_array_size, sizeof(time_t)); |
375 |
367 |
char *tmp_pray[6]; /* string array hold temp values for checking */ |
char *tmp_pray[6]; /* string array hold temp values for checking */ |
376 |
368 |
|
|
377 |
|
/* To fix splint warning Returned storage not completely defined */ |
|
378 |
|
pray_times_array[0] = 0; |
|
379 |
|
|
|
380 |
|
/* Read the cache file */ |
|
|
369 |
|
/* Read the cache file */ |
381 |
370 |
fp = fopen(azan_cache_file,"r"); |
fp = fopen(azan_cache_file,"r"); |
382 |
371 |
FAIL_IF(fp == NULL, "[Error] opening azan cache file."); |
FAIL_IF(fp == NULL, "[Error] opening azan cache file."); |
383 |
372 |
|
|
|
... |
... |
static time_t |
395 |
384 |
return pray_times_array; |
return pray_times_array; |
396 |
385 |
} |
} |
397 |
386 |
|
|
398 |
|
static int |
|
399 |
|
print_next_prayer(const time_t current_time, const char *azan_cache_file) |
|
|
387 |
|
static time_t |
|
388 |
|
*get_all_prayers(const time_t t) |
400 |
389 |
{ |
{ |
401 |
|
time_t *azan_array; |
|
402 |
|
azan_array = read_azan_cache_file(azan_cache_file); |
|
403 |
|
FAIL_IF(azan_array == NULL, "[Error] reading array."); |
|
|
390 |
|
time_t *prayer_array; /* the returned array */ |
|
391 |
|
size_t prayer_array_size= (size_t)6; |
|
392 |
|
prayer_array = ecalloc(prayer_array_size, sizeof(time_t)); |
404 |
393 |
|
|
405 |
|
for (int i=0; i<6; i++) { |
|
406 |
|
if (azan_array[i] > current_time){ |
|
407 |
|
double left_seconds = difftime(azan_array[i], current_time); |
|
408 |
|
char prayer_first_letter = convert_prayer_int_to_char(i); |
|
409 |
|
char *left_duration = convert_sec_double_to_min_hour(left_seconds); |
|
410 |
|
printf("%c %s\n", prayer_first_letter, left_duration); |
|
411 |
|
free(left_duration); |
|
412 |
|
break; /* Print first prayer only */ |
|
413 |
|
} |
|
414 |
|
} |
|
|
394 |
|
/* Current date time */ |
|
395 |
|
const struct tm current_date = *localtime(&t); |
|
396 |
|
const int day = current_date.tm_mday; |
|
397 |
|
const int month = current_date.tm_mon + 1; |
|
398 |
|
const int year = current_date.tm_year + 1900; |
415 |
399 |
|
|
416 |
|
free(azan_array); |
|
417 |
|
azan_array = NULL; |
|
418 |
|
return 0; |
|
|
400 |
|
/* Equation of Time */ |
|
401 |
|
const double julian_date = convert_gregorian_to_julian( |
|
402 |
|
year, month, day); |
|
403 |
|
double D = 0.0; |
|
404 |
|
const double equation_of_time = get_equation_time(julian_date, &D); |
|
405 |
|
|
|
406 |
|
/* Today's Prayers time */ |
|
407 |
|
const double duhr = get_duhr(equation_of_time); |
|
408 |
|
const double fajr = get_fajr(duhr, D); |
|
409 |
|
const double maghrib = get_maghrib(duhr, D); |
|
410 |
|
const double isha = get_isha(duhr, maghrib, D); |
|
411 |
|
const double asr = get_asr(duhr, D); |
|
412 |
|
|
|
413 |
|
/* Convert prayer times to unix timestamp */ |
|
414 |
|
/* time_t prayer_array[6]; */ |
|
415 |
|
prayer_array[0] = convert_today_double_to_timet(fajr, day); |
|
416 |
|
prayer_array[1] = convert_today_double_to_timet(duhr, day); |
|
417 |
|
prayer_array[2] = convert_today_double_to_timet(asr, day); |
|
418 |
|
prayer_array[3] = convert_today_double_to_timet(maghrib, day); |
|
419 |
|
prayer_array[4] = convert_today_double_to_timet(isha, day); |
|
420 |
|
prayer_array[5] = convert_today_double_to_timet(fajr, day+1); |
|
421 |
|
|
|
422 |
|
/* printf("%ld\n%ld\n%ld\n%ld\n%ld\n%ld\n", |
|
423 |
|
// (long)prayer_array[0], |
|
424 |
|
// (long)prayer_array[1], |
|
425 |
|
// (long)prayer_array[2], |
|
426 |
|
// (long)prayer_array[3], |
|
427 |
|
// (long)prayer_array[4], |
|
428 |
|
// (long)prayer_array[5] |
|
429 |
|
); |
|
430 |
|
*/ |
|
431 |
|
|
|
432 |
|
FAIL_IF(prayer_array == NULL, "[Error] pray_times_array is NULL."); |
|
433 |
|
return prayer_array; |
419 |
434 |
} |
} |
420 |
435 |
|
|
421 |
436 |
static int |
static int |
422 |
|
print_all_prayers(const char *azan_cache_file) |
|
|
437 |
|
print_p(const char print_m, const char cache_m) |
423 |
438 |
{ |
{ |
|
439 |
|
/* |
|
440 |
|
* print_m: [n] next prayer, [a] all prayers |
|
441 |
|
* cache_m: [r] runtime, [c] use cache file |
|
442 |
|
*/ |
|
443 |
|
|
|
444 |
|
const time_t current_time = time(NULL); |
424 |
445 |
time_t *azan_array; |
time_t *azan_array; |
425 |
|
azan_array = read_azan_cache_file(azan_cache_file); |
|
426 |
|
FAIL_IF(azan_array == NULL, "[Error] reading array."); |
|
|
446 |
|
char *prayer_time; |
|
447 |
|
char *left_duration; |
|
448 |
|
char *azan_cache_file; |
|
449 |
|
char prayer_first_letter; |
|
450 |
|
double left_seconds; |
|
451 |
|
|
|
452 |
|
switch (cache_m) { |
|
453 |
|
case 'r': /* runtime, no caching */ |
|
454 |
|
azan_array = get_all_prayers(current_time); |
|
455 |
|
FAIL_IF(azan_array == NULL, "[Error] reading array."); |
|
456 |
|
break; |
|
457 |
|
|
|
458 |
|
case 'c': /* use cache file */ |
|
459 |
|
/* Create cache file if not exists */ |
|
460 |
|
azan_cache_file = get_cache_file_name(current_time); |
|
461 |
|
FAIL_IF(create_cache_file(current_time, azan_cache_file) < 0, |
|
462 |
|
"[Error] creating Cache File."); |
|
463 |
|
azan_array = read_azan_cache_file(azan_cache_file); |
|
464 |
|
FAIL_IF(azan_array == NULL, "[Error] reading array."); |
|
465 |
|
free(azan_cache_file); |
|
466 |
|
azan_cache_file = NULL; |
|
467 |
|
break; |
|
468 |
|
} |
427 |
469 |
|
|
428 |
|
for (int i=0; i<5; i++) { |
|
429 |
|
// convert_timet_to_str; |
|
430 |
|
const char prayer_first_letter = convert_prayer_int_to_char(i); |
|
431 |
|
char *prayer_time = convert_timet_to_str(azan_array[i]); |
|
432 |
|
printf("%c %s\n", prayer_first_letter, prayer_time); |
|
433 |
|
free(prayer_time); |
|
|
470 |
|
switch (print_m) { |
|
471 |
|
case 'a': /* print all prayers time */ |
|
472 |
|
for (int i=0; i<5; i++) { |
|
473 |
|
prayer_first_letter = convert_prayer_int_to_char(i); |
|
474 |
|
prayer_time = convert_timet_to_str(azan_array[i]); |
|
475 |
|
printf("%c %s\n", prayer_first_letter, prayer_time); |
|
476 |
|
free(prayer_time); |
|
477 |
|
prayer_time = NULL; |
|
478 |
|
} |
|
479 |
|
break; |
|
480 |
|
case 'n': /* print next prayer left duration */ |
|
481 |
|
for (int i=0; i<6; i++) { |
|
482 |
|
if (azan_array[i] > current_time){ |
|
483 |
|
left_seconds = difftime(azan_array[i], current_time); |
|
484 |
|
prayer_first_letter = convert_prayer_int_to_char(i); |
|
485 |
|
left_duration = convert_sec_double_to_min_hour(left_seconds); |
|
486 |
|
printf("%c %s\n", prayer_first_letter, left_duration); |
|
487 |
|
free(left_duration); |
|
488 |
|
left_duration = NULL; |
|
489 |
|
break; /* Print first prayer only */ |
|
490 |
|
} |
|
491 |
|
} |
|
492 |
|
break; |
434 |
493 |
} |
} |
435 |
494 |
|
|
436 |
495 |
free(azan_array); |
free(azan_array); |
|
496 |
|
azan_array = NULL; |
437 |
497 |
return 0; |
return 0; |
438 |
|
} |
|
439 |
|
|
|
440 |
|
static char |
|
441 |
|
*get_cache_file_name(const time_t t) |
|
442 |
|
{ |
|
443 |
|
/* Current date time */ |
|
444 |
|
const struct tm current_date = *localtime(&t); |
|
445 |
|
const int day = current_date.tm_mday; |
|
446 |
|
const int month = current_date.tm_mon + 1; |
|
447 |
|
const int year = current_date.tm_year + 1900; |
|
448 |
|
|
|
449 |
|
const size_t max_file_name = (size_t)128; |
|
450 |
|
char azan_cache_file[128]; |
|
451 |
|
|
|
452 |
|
(void)snprintf(azan_cache_file, max_file_name, "azan_%.2i-%.2i-%i.txt", |
|
453 |
|
day, month, year); |
|
454 |
498 |
|
|
455 |
|
char *full_path = calloc(max_file_name, sizeof(char)); |
|
456 |
|
FAIL_IF(full_path == NULL,"[Error] reading array."); |
|
457 |
|
strcpy(full_path, cache_dir); |
|
458 |
|
strcat(full_path, "/"); |
|
459 |
|
strcat(full_path, azan_cache_file); |
|
460 |
|
|
|
461 |
|
return full_path; |
|
462 |
499 |
} |
} |
463 |
500 |
|
|
464 |
501 |
int |
int |
465 |
502 |
main(int argc, char *argv[]) |
main(int argc, char *argv[]) |
466 |
503 |
{ |
{ |
467 |
|
/* Handel Arguments */ |
|
468 |
|
const int c = getopt(argc, argv, "vah"); |
|
469 |
|
const time_t t = time(NULL); |
|
470 |
|
char *full_path = get_cache_file_name(t); |
|
471 |
|
|
|
472 |
|
if (argc > 1) { |
|
473 |
|
switch (c) { |
|
474 |
|
case 'v': |
|
|
504 |
|
if (argc == 1) { |
|
505 |
|
FAIL_IF(print_p('n', 'r') < 0, "Error Calculating.\n"); |
|
506 |
|
|
|
507 |
|
} else if (argc > 1) { |
|
508 |
|
if (strcmp("-v", argv[1]) == 0){ |
475 |
509 |
(void)puts("azan-"VERSION); |
(void)puts("azan-"VERSION); |
476 |
|
break; |
|
477 |
|
case 'a': |
|
478 |
|
FAIL_IF(create_cache_file(t, full_path) < 0, |
|
479 |
|
"[Error] Creating Cache File."); |
|
480 |
|
FAIL_IF(print_all_prayers(full_path) < 0, |
|
481 |
|
"[Error] print_all_prayers()."); |
|
482 |
|
break; |
|
483 |
|
case 'h': |
|
484 |
|
usage(); |
|
485 |
|
break; |
|
486 |
|
default: |
|
|
510 |
|
|
|
511 |
|
} else if (strcmp("-h", argv[1]) == 0){ |
487 |
512 |
usage(); |
usage(); |
488 |
|
} |
|
489 |
513 |
|
|
490 |
|
/* No Argument */ |
|
491 |
|
} else { |
|
|
514 |
|
} else if (strcmp("-a", argv[1]) == 0){ |
|
515 |
|
FAIL_IF(print_p('a', 'r') < 0, "Error Calculating.\n"); |
492 |
516 |
|
|
493 |
|
/* Create cache file if not exists */ |
|
494 |
|
if (create_cache_file(t, full_path) < 0) { |
|
495 |
|
printf("Error Creating Cache File\n"); |
|
496 |
|
free(full_path); |
|
497 |
|
full_path = NULL; |
|
498 |
|
return -1; |
|
499 |
|
} |
|
|
517 |
|
} else if (strcmp("-c", argv[1]) == 0){ |
|
518 |
|
FAIL_IF(print_p('n', 'c') < 0, "Error Reading Cache File\n"); |
500 |
519 |
|
|
501 |
|
/* Read cache file */ |
|
502 |
|
if (print_next_prayer(t, full_path) < 0){ |
|
503 |
|
printf("Error Reading Cache File\n"); |
|
504 |
|
free(full_path); |
|
505 |
|
full_path = NULL; |
|
506 |
|
return -1; |
|
|
520 |
|
} else if (strcmp("-ca", argv[1]) == 0 || strcmp("-ac", argv[1]) == 0){ |
|
521 |
|
FAIL_IF(print_p('a', 'c') < 0, "[Error] print_all_prayers()."); |
507 |
522 |
} |
} |
508 |
523 |
} |
} |
509 |
|
free(full_path); |
|
510 |
|
full_path = NULL; |
|
511 |
524 |
return 0; |
return 0; |
512 |
525 |
} |
} |