fordon_greeman / pkger

Branch: 02f8442
Switch branches/tags
main
theidioticdev feat: use tsoding's nob.h, split repos.h into separate recipes 02f8442 13d ago
141 lines · 2.8 KB Raw Blame History
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <sys/wait.h>
6 #include <sys/stat.h>
7 #include <dirent.h>
8 #include <errno.h>
9 #include "recipe.h"
10
11 int
12 run_cmd (char *const argv[])
13 {
14 pid_t pid = fork ();
15 if (pid == 0)
16 {
17 execvp (argv[0], argv);
18 perror ("execvp failed");
19 _exit (1);
20 }
21 else if (pid > 0)
22 {
23 int status;
24 waitpid (pid, &status, 0);
25 return WIFEXITED (status) && WEXITSTATUS (status) == 0;
26 }
27 return 0;
28 }
29
30 int
31 run_shell_string (const char *cmd)
32 {
33 if (!cmd || strlen (cmd) == 0)
34 return 1;
35
36 if (strcmp (cmd, "true") == 0)
37 return 1;
38
39 printf ("[EXEC] %s\n", cmd);
40 char *const argv[] = { "/bin/sh", "-c", (char *) cmd, NULL };
41 return run_cmd (argv);
42 }
43
44 void
45 install_repo (const Repository *repo)
46 {
47 printf ("[INSTALL] %s\n", repo->name);
48
49 char repo_dir[256];
50 char *home = getenv("HOME");
51 if (home) snprintf (repo_dir, sizeof (repo_dir), "%s/.cache/pkger/%s", home, repo->name);
52
53 char fetch_str[512];
54 snprintf (fetch_str, sizeof (fetch_str), repo->fetchFmt, repo->fetchCmd,
55 repo->url, repo_dir);
56 if (!run_shell_string (fetch_str))
57 {
58 fprintf (stderr, "[ERROR] Failed to fetch package.\n");
59 return;
60 }
61
62 if (chdir (repo_dir) != 0)
63 {
64 perror ("[ERROR] chdir failed");
65 return;
66 }
67
68 if (!run_shell_string (repo->buildCmd))
69 {
70 fprintf (stderr, "Build failed.\n");
71 return;
72 }
73
74 if (!run_shell_string (repo->installCmd))
75 {
76 fprintf (stderr, "Install failed.\n");
77 return;
78 }
79
80 printf ("[INSTALL] installed %s\n", repo->name);
81 }
82
83 void
84 uninstall_repo (const Repository *repo)
85 {
86 char repo_dir[256];
87 snprintf (repo_dir, sizeof (repo_dir), "/tmp/pkger-%s", repo->name);
88
89 if (chdir (repo_dir) != 0)
90 {
91 perror ("[ERROR] chdir failed");
92 return;
93 }
94
95 printf ("[UNINSTALL] %s\n", repo->name);
96 if (!run_shell_string (repo->uninstallCmd))
97 {
98 fprintf (stderr, "[ERROR] uninstall failed.\n");
99 }
100 }
101
102 int
103 main (int argc, char *argv[])
104 {
105 if (argc < 3)
106 {
107 printf ("Usage: %s <install|uninstall> <repo_name>\n", argv[0]);
108 printf ("\nAvailable packages:\n");
109 for (size_t i = 0; i < REPO_COUNT; i++)
110 {
111 printf (" - %s\n", REPOS[i].name);
112 }
113 return 1;
114 }
115
116 const char *action = argv[1];
117 const char *target = argv[2];
118
119 for (size_t i = 0; i < REPO_COUNT; i++)
120 {
121 if (strcmp (REPOS[i].name, target) == 0)
122 {
123 if (strcmp (action, "install") == 0)
124 {
125 install_repo (&REPOS[i]);
126 }
127 else if (strcmp (action, "uninstall") == 0)
128 {
129 uninstall_repo (&REPOS[i]);
130 }
131 else
132 {
133 fprintf (stderr, "Unknown action: %s\n", action);
134 }
135 return 0;
136 }
137 }
138
139 fprintf (stderr, "Repository '%s' not found.\n", target);
140 return 1;
141 }