fordon_greeman / pkger

Branch: c2d1d35
Switch branches/tags
main
theidioticdev feat: support more than just git, guix pkg test, port bs from c to shell c2d1d35 18d ago
139 lines · 3 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 "repos.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 ("=== Installing %s ===\n", repo->name);
48
49 char repo_dir[256];
50 snprintf (repo_dir, sizeof (repo_dir), "/tmp/pkger-%s", repo->name);
51
52 char fetch_str[512];
53 snprintf (fetch_str, sizeof (fetch_str), repo->fetchFmt, repo->fetchCmd, repo->url, repo_dir);
54 if (!run_shell_string (fetch_str))
55 {
56 fprintf (stderr, "[ERROR] Failed to fetch package.\n");
57 return;
58 }
59
60 if (chdir (repo_dir) != 0)
61 {
62 perror ("[ERROR] chdir failed");
63 return;
64 }
65
66 if (!run_shell_string (repo->buildCmd))
67 {
68 fprintf (stderr, "Build failed.\n");
69 return;
70 }
71
72 if (!run_shell_string (repo->installCmd))
73 {
74 fprintf (stderr, "Install failed.\n");
75 return;
76 }
77
78 printf ("Successfully installed %s!\n", repo->name);
79 }
80
81 void
82 uninstall_repo (const Repository *repo)
83 {
84 char repo_dir[256];
85 snprintf (repo_dir, sizeof (repo_dir), "/tmp/pkger-%s", repo->name);
86
87 if (chdir (repo_dir) != 0)
88 {
89 perror ("[ERROR] chdir failed");
90 return;
91 }
92
93 printf ("=== Uninstalling %s ===\n", repo->name);
94 if (!run_shell_string (repo->uninstallCmd))
95 {
96 fprintf (stderr, "Uninstall failed.\n");
97 }
98 }
99
100 int
101 main (int argc, char *argv[])
102 {
103 if (argc < 3)
104 {
105 printf ("Usage: %s <install|uninstall> <repo_name>\n", argv[0]);
106 printf ("\nAvailable repositories:\n");
107 for (size_t i = 0; i < REPO_COUNT; i++)
108 {
109 printf (" - %s\n", REPOS[i].name);
110 }
111 return 1;
112 }
113
114 const char *action = argv[1];
115 const char *target = argv[2];
116
117 for (size_t i = 0; i < REPO_COUNT; i++)
118 {
119 if (strcmp (REPOS[i].name, target) == 0)
120 {
121 if (strcmp (action, "install") == 0)
122 {
123 install_repo (&REPOS[i]);
124 }
125 else if (strcmp (action, "uninstall") == 0)
126 {
127 uninstall_repo (&REPOS[i]);
128 }
129 else
130 {
131 fprintf (stderr, "Unknown action: %s\n", action);
132 }
133 return 0;
134 }
135 }
136
137 fprintf (stderr, "Repository '%s' not found.\n", target);
138 return 1;
139 }