11#include "include/archium.h"
22
3+ #define CACHE_TTL_SECONDS 3600
4+ #define PACKAGE_CACHE_FILE "packages.cache"
5+
6+ static int is_cache_valid (const char * cache_path ) {
7+ struct stat cache_stat ;
8+ if (stat (cache_path , & cache_stat ) != 0 ) {
9+ return 0 ;
10+ }
11+
12+ time_t now = time (NULL );
13+ return (now - cache_stat .st_mtime ) < CACHE_TTL_SECONDS ;
14+ }
15+
16+ static void load_cache_from_file (const char * cache_path ) {
17+ FILE * fp = fopen (cache_path , "r" );
18+ if (!fp ) {
19+ return ;
20+ }
21+
22+ char line [256 ];
23+ int command_count = 0 ;
24+
25+ while (fgets (line , sizeof (line ), fp ) != NULL ) {
26+ line [strcspn (line , "\n" )] = 0 ;
27+ if (strlen (line ) == 0 ) continue ;
28+
29+ command_count ++ ;
30+ cached_commands =
31+ realloc (cached_commands , sizeof (char * ) * (command_count + 1 ));
32+ cached_commands [command_count - 1 ] = strdup (line );
33+ }
34+
35+ fclose (fp );
36+
37+ const char * custom_cmds [] = {"check" , "info" , "s" };
38+ for (int i = 0 ; i < 3 ; i ++ ) {
39+ command_count ++ ;
40+ cached_commands =
41+ realloc (cached_commands , sizeof (char * ) * (command_count + 1 ));
42+ cached_commands [command_count - 1 ] = strdup (custom_cmds [i ]);
43+ }
44+
45+ if (cached_commands ) {
46+ cached_commands [command_count ] = NULL ;
47+ }
48+ }
49+
50+ static void save_cache_to_file (const char * cache_path ) {
51+ FILE * fp = fopen (cache_path , "w" );
52+ if (!fp ) {
53+ return ;
54+ }
55+
56+ for (int i = 0 ; cached_commands && cached_commands [i ] != NULL ; i ++ ) {
57+ if (strcmp (cached_commands [i ], "check" ) != 0 &&
58+ strcmp (cached_commands [i ], "info" ) != 0 &&
59+ strcmp (cached_commands [i ], "s" ) != 0 ) {
60+ fprintf (fp , "%s\n" , cached_commands [i ]);
61+ }
62+ }
63+
64+ fclose (fp );
65+ }
66+
367void cache_pacman_commands (void ) {
468 if (cached_commands ) {
569 return ;
670 }
771
72+ const char * cache_dir = archium_config_get_cache_dir ();
73+ if (!cache_dir ) {
74+ fprintf (stderr , "\033[1;31mError: Failed to get cache directory.\033[0m\n" );
75+ return ;
76+ }
77+
78+ char cache_path [512 ];
79+ if (snprintf (cache_path , sizeof (cache_path ), "%s/%s" , cache_dir ,
80+ PACKAGE_CACHE_FILE ) >= (int )sizeof (cache_path )) {
81+ fprintf (stderr , "\033[1;31mError: Cache path too long.\033[0m\n" );
82+ return ;
83+ }
84+
85+ if (is_cache_valid (cache_path )) {
86+ load_cache_from_file (cache_path );
87+ if (cached_commands ) {
88+ log_debug ("Loaded package list from cache" );
89+ return ;
90+ }
91+ }
92+
893 FILE * fp ;
994 char path [1035 ];
1095 int command_count = 0 ;
1196
1297 fp = popen ("pacman -Ssq" , "r" );
1398 if (fp == NULL ) {
1499 fprintf (stderr , "\033[1;31mFailed to run command\033[0m\n" );
15- exit ( EXIT_FAILURE ) ;
100+ return ;
16101 }
17102
18103 while (fgets (path , sizeof (path ), fp ) != NULL ) {
@@ -36,6 +121,9 @@ void cache_pacman_commands(void) {
36121 if (cached_commands ) {
37122 cached_commands [command_count ] = NULL ;
38123 }
124+
125+ save_cache_to_file (cache_path );
126+ log_debug ("Generated and cached package list" );
39127}
40128
41129char * command_generator (const char * text , int state ) {
@@ -68,6 +156,22 @@ char **command_completion(const char *text, int start, int end) {
68156 return rl_completion_matches (text , command_generator );
69157}
70158
159+ void invalidate_package_cache (void ) {
160+ const char * cache_dir = archium_config_get_cache_dir ();
161+ if (!cache_dir ) {
162+ return ;
163+ }
164+
165+ char cache_path [512 ];
166+ if (snprintf (cache_path , sizeof (cache_path ), "%s/%s" , cache_dir ,
167+ PACKAGE_CACHE_FILE ) >= (int )sizeof (cache_path )) {
168+ return ;
169+ }
170+
171+ unlink (cache_path );
172+ log_debug ("Invalidated package cache" );
173+ }
174+
71175void cleanup_cached_commands (void ) {
72176 if (cached_commands ) {
73177 for (int i = 0 ; cached_commands [i ] != NULL ; i ++ ) {
0 commit comments