mirror of the now-defunct rocklinux.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

258 lines
4.7 KiB

  1. /* Bash (wallclock-time) profiler. Written by Clifford Wolf.
  2. *
  3. * Usage:
  4. * gcc -shared -fPIC -Wall -o config_helper.so config_helper.c
  5. * enable -f ./config_helper.so cfghlp
  6. *
  7. * Note: This builtin trusts that it is called correctly. If it is
  8. * called the wrong way, segfaults etc. are possible.
  9. */
  10. /* Some declarations copied from bash-2.05b headers */
  11. #include <stdint.h>
  12. typedef struct word_desc {
  13. char *word;
  14. int flags;
  15. } WORD_DESC;
  16. typedef struct word_list {
  17. struct word_list *next;
  18. WORD_DESC *word;
  19. } WORD_LIST;
  20. typedef int sh_builtin_func_t(WORD_LIST *);
  21. #define BUILTIN_ENABLED 0x1
  22. struct builtin {
  23. char *name;
  24. sh_builtin_func_t *function;
  25. int flags;
  26. char * const *long_doc;
  27. const char *short_doc;
  28. char *handle;
  29. };
  30. /* my hellobash builtin */
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #include <sys/time.h>
  35. struct package;
  36. struct package {
  37. int status;
  38. char stages[10];
  39. char *prio;
  40. char *repository;
  41. char *name;
  42. char *alias;
  43. char *version;
  44. char *prefix;
  45. char *flags;
  46. struct package *next;
  47. };
  48. struct package *package_list = 0;
  49. int read_pkg_list(const char *file) {
  50. FILE *f = fopen(file, "r");
  51. struct package *pkg = package_list;
  52. struct package *pkg_tmp;
  53. char line[1024], *tok;
  54. int i;
  55. while (pkg) {
  56. free(pkg->prio);
  57. free(pkg->repository);
  58. free(pkg->name);
  59. free(pkg->alias);
  60. free(pkg->version);
  61. free(pkg->prefix);
  62. free(pkg->flags);
  63. pkg = (pkg_tmp=pkg)->next;
  64. free(pkg_tmp);
  65. }
  66. pkg = package_list = 0;
  67. while (fgets(line, 1024, f)) {
  68. pkg_tmp = calloc(1, sizeof(struct package));
  69. tok = strtok(line, " ");
  70. pkg_tmp->status = line[0] == 'X';
  71. tok = strtok(0, " ");
  72. for (i=0; i<10; i++)
  73. pkg_tmp->stages[i] = tok[i] != '-' ? tok[i] : 0;
  74. tok = strtok(0, " ");
  75. pkg_tmp->prio = strdup(tok);
  76. tok = strtok(0, " ");
  77. pkg_tmp->repository = strdup(tok);
  78. tok = strtok(0, " ");
  79. pkg_tmp->name = strdup(tok);
  80. pkg_tmp->alias = strdup(tok);
  81. tok = strtok(0, " ");
  82. pkg_tmp->version = strdup(tok);
  83. tok = strtok(0, " ");
  84. pkg_tmp->prefix = strdup(tok);
  85. tok = strtok(0, "\n");
  86. tok[strlen(tok)-2] = 0;
  87. pkg_tmp->flags = strdup(tok);
  88. if ( !package_list )
  89. pkg=package_list=pkg_tmp;
  90. else
  91. pkg=pkg->next=pkg_tmp;
  92. }
  93. fclose(f);
  94. return 0;
  95. }
  96. int write_pkg_list(const char *file) {
  97. FILE *f = fopen(file, "w");
  98. struct package *pkg = package_list;
  99. int i;
  100. while (pkg) {
  101. fprintf(f, "%c ", pkg->status ? 'X' : 'O');
  102. for (i=0; i<10; i++)
  103. fprintf(f, "%c", pkg->stages[i] ? pkg->stages[i] : '-');
  104. fprintf(f, " %s %s %s", pkg->prio, pkg->repository, pkg->name);
  105. if (strcmp(pkg->name, pkg->alias))
  106. fprintf(f, "=%s", pkg->alias);
  107. fprintf(f, " %s %s %s 0\n", pkg->version, pkg->prefix, pkg->flags);
  108. pkg = pkg->next;
  109. }
  110. fclose(f);
  111. return 0;
  112. }
  113. int pkgcheck(const char *pattern, const char *mode)
  114. {
  115. struct package *pkg = package_list;
  116. char *pattern_copy = strdup(pattern);
  117. char *pat_list[10];
  118. int i;
  119. pat_list[0] = strtok(pattern_copy, "|");
  120. for (i=1; i<10; i++)
  121. if ( !(pat_list[i] = strtok(0, "|")) ) break;
  122. while (pkg) {
  123. for (i=0; i<10 && pat_list[i]; i++)
  124. if (!strcmp(pkg->alias, pat_list[i]))
  125. switch (mode[0]) {
  126. case 'X':
  127. if (pkg->status) goto found;
  128. break;
  129. case 'O':
  130. if (!pkg->status) goto found;
  131. break;
  132. case '.':
  133. goto found;
  134. }
  135. pkg = pkg->next;
  136. }
  137. free(pattern_copy);
  138. return 1;
  139. found:
  140. free(pattern_copy);
  141. return 0;
  142. }
  143. int pkgswitch(int mode, char **args)
  144. {
  145. struct package *pkg = package_list;
  146. struct package *last_pkg = 0;
  147. struct package *pkg_tmp = 0;
  148. int i;
  149. while (pkg) {
  150. for (i=0; *args[i]; i++)
  151. if (!strcmp(pkg->alias, args[i])) {
  152. if ( !mode ) {
  153. *(last_pkg ? &(last_pkg->next) : &package_list) = pkg->next;
  154. free(pkg->prio);
  155. free(pkg->repository);
  156. free(pkg->name);
  157. free(pkg->alias);
  158. free(pkg->version);
  159. free(pkg->prefix);
  160. free(pkg->flags);
  161. pkg = (pkg_tmp=pkg)->next;
  162. free(pkg_tmp);
  163. continue;
  164. } else
  165. pkg->status = mode == 1;
  166. }
  167. pkg = (last_pkg=pkg)->next;
  168. }
  169. return 0;
  170. }
  171. int cfghlp_builtin(WORD_LIST *list)
  172. {
  173. char *args[10];
  174. int i;
  175. for (i=0; i<9 && list; i++) {
  176. args[i] = list->word->word;
  177. list = list->next;
  178. }
  179. for (; i<10; i++) {
  180. args[i] = "";
  181. }
  182. if (!strcmp(args[0],"pkg_in"))
  183. return read_pkg_list(args[1]);
  184. if (!strcmp(args[0],"pkg_out"))
  185. return write_pkg_list(args[1]);
  186. if (!strcmp(args[0],"pkgcheck"))
  187. return pkgcheck(args[1], args[2]);
  188. if (!strcmp(args[0],"pkgremove"))
  189. return pkgswitch(0, args+1);
  190. if (!strcmp(args[0],"pkgenable"))
  191. return pkgswitch(1, args+1);
  192. if (!strcmp(args[0],"pkgdisable"))
  193. return pkgswitch(2, args+1);
  194. return 1;
  195. }
  196. char *cfghlp_doc[] = {
  197. "ROCK Linux Config Helper",
  198. 0
  199. };
  200. struct builtin cfghlp_struct = {
  201. "cfghlp",
  202. &cfghlp_builtin,
  203. BUILTIN_ENABLED,
  204. cfghlp_doc,
  205. "ROCK Linux Config Helper",
  206. 0
  207. };