envreg.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. envreg - Register TIGCC environment variables into bashrc
  3. Copyright (C) 2004 Kevin Kofler
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software Foundation,
  14. Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <unistd.h>
  20. int main(void) {
  21. char *bashrc;
  22. char *tigcc;
  23. char *oldtigcc=NULL;
  24. FILE *f=NULL;
  25. char **lines=NULL;
  26. int numlines=0;
  27. int i;
  28. char *p;
  29. // Find out what bashrc file to use
  30. if (geteuid()) {
  31. const char *homedir;
  32. puts("envreg: Running as normal user");
  33. homedir=getenv("HOME");
  34. if (!homedir) {
  35. puts("envreg: error: $HOME not set");
  36. return 1;
  37. }
  38. bashrc=malloc(strlen(homedir)+9);
  39. if (!bashrc) goto outofmem;
  40. strcpy(bashrc,homedir);
  41. if (bashrc[strlen(bashrc)-1]!='/') strcat(bashrc,"/");
  42. strcat(bashrc,".bashrc");
  43. } else {
  44. puts("envreg: Running as root");
  45. bashrc=malloc(12);
  46. if (!bashrc) goto outofmem;
  47. strcpy(bashrc,"/etc/bashrc");
  48. }
  49. printf("envreg: Using bashrc file: `%s'\n",bashrc);
  50. // Read the current file contents
  51. f=fopen(bashrc,"rb");
  52. // If we can't open the file, assume it doesn't exist and treat it as empty
  53. if (f) {
  54. // Get the file size
  55. fseek(f,0,SEEK_END);
  56. i=ftell(f);
  57. fseek(f,0,SEEK_SET);
  58. // Allocate a buffer for the entire file and read it into memory
  59. lines=malloc(sizeof(unsigned char *));
  60. if (!lines) goto outofmem;
  61. *lines=malloc(i+1);
  62. if (!*lines) goto outofmem;
  63. fread(*lines,1,i,f);
  64. (*lines)[i]=0;
  65. // Close the file
  66. fclose(f);
  67. f=NULL;
  68. // Now split the file into lines
  69. while((p=strchr(lines[numlines],'\n'))) {
  70. lines=realloc(lines,((++numlines)+1)*sizeof(unsigned char *));
  71. if (!lines) goto outofmem;
  72. lines[numlines]=malloc(strlen(p+1)+1);
  73. if (!lines[numlines]) goto outofmem;
  74. strcpy(lines[numlines],p+1);
  75. *p=0;
  76. if (p[-1]=='\r') p[-1]=0;
  77. lines[numlines-1]=realloc(lines[numlines-1],strlen(lines[numlines-1])+1);
  78. if (!lines[numlines-1]) goto outofmem; // Some stupid systems copy even when cutting.
  79. }
  80. // If the last line is empty, drop it, else count it
  81. if (*(lines[numlines])) numlines++; else {
  82. free(lines[numlines]);
  83. lines=realloc(lines,numlines*sizeof(unsigned char *));
  84. if (!lines) goto outofmem; // Some stupid systems copy even when cutting.
  85. }
  86. } else {
  87. printf("envreg: `%s' doesn't exist, creating a new one\n",bashrc);
  88. }
  89. // Look for existing $TIGCC setting
  90. for (i=0;i<numlines;i++) {
  91. if (!strncmp(lines[i],"export TIGCC=",13)) {
  92. // Get old $TIGCC setting
  93. oldtigcc=malloc(strlen(lines[i])-12);
  94. strcpy(oldtigcc,lines[i]+13+(lines[i][13]=='\"'));
  95. if (oldtigcc[strlen(oldtigcc)-1]=='\"') oldtigcc[strlen(oldtigcc)-1]=0;
  96. printf("envreg: $TIGCC previously set to `%s'\n",oldtigcc);
  97. break;
  98. }
  99. }
  100. if (i==numlines) {
  101. // Add new $TIGCC setting
  102. i=numlines;
  103. lines=realloc(lines,++numlines*sizeof(unsigned char *));
  104. if (!lines) goto outofmem;
  105. lines[i]=NULL;
  106. }
  107. // Add the setting
  108. tigcc=getenv("TIGCC");
  109. if (!tigcc) {
  110. puts("envreg: error: $TIGCC not set");
  111. return 1;
  112. }
  113. printf("envreg: setting $TIGCC to `%s'\n",tigcc);
  114. lines[i]=realloc(lines[i],strlen(tigcc)+16);
  115. if (!lines[i]) goto outofmem;
  116. strcpy(lines[i],"export TIGCC=\"");
  117. strcat(lines[i],tigcc);
  118. strcat(lines[i],"\"");
  119. if (oldtigcc) {
  120. // Append "/bin" to oldtigcc
  121. oldtigcc=realloc(oldtigcc,strlen(oldtigcc)+5);
  122. if (!oldtigcc) goto outofmem;
  123. if (oldtigcc[strlen(oldtigcc)-1]!='/') strcat(oldtigcc,"/");
  124. strcat(oldtigcc,"bin");
  125. }
  126. // Look for existing $PATH settings
  127. for (i=0;i<numlines;i++) {
  128. if (!strncmp(lines[i],"export PATH=",12)) {
  129. // Check if it contains literal $TIGCC/bin
  130. if (strstr(lines[i],"$TIGCC/bin")) {
  131. puts("envreg: $PATH already contains $TIGCC/bin");
  132. goto writeout;
  133. }
  134. // Check if it contains old $TIGCC/bin
  135. while (oldtigcc && (p=strstr(lines[i],oldtigcc))
  136. && (p[-1]=='='||(p[-1]=='\"'&&p[-2]=='=')||p[-1]==':')) {
  137. int l;
  138. printf("envreg: $PATH contains `%s', removing\n",oldtigcc);
  139. l=strlen(oldtigcc);
  140. while (p[l] && p[l]!='\"' && p[l]!=':') l++; // look for end
  141. if ((!p[l]||(p[l]=='\"'&&!p[l+1]))
  142. && (p[-1]=='='||(p[-1]=='\"'&&p[-2]=='=')))
  143. *(lines[i])=0; // single entry, so zap entire line
  144. if ((!p[l]||(p[l]=='\"'&&!p[l+1]))) p--; // last entry, must zap : in
  145. // in front, not afterwards
  146. l++; // zap :
  147. memmove(p,p+l,strlen(p+l)+1);
  148. }
  149. }
  150. }
  151. // Add new $PATH setting
  152. puts("envreg: appending $TIGCC/bin to $PATH");
  153. i=numlines;
  154. lines=realloc(lines,++numlines*sizeof(unsigned char *));
  155. if (!lines) goto outofmem;
  156. lines[i]=malloc(31);
  157. strcpy(lines[i],"export PATH=\"$PATH:$TIGCC/bin\"");
  158. writeout:
  159. // Write out the new file
  160. f=fopen(bashrc,"wt");
  161. // If we can't open the file, now, we have a permissions problem
  162. if (!f) {
  163. printf("envreg: error: can't write to `%s'\n",bashrc);
  164. return 1;
  165. }
  166. // Write out each line
  167. for (i=0;i<numlines;i++) {
  168. fprintf(f,"%s\n",lines[i]);
  169. }
  170. // Close the file
  171. fclose(f);
  172. f=NULL;
  173. return 0;
  174. outofmem:
  175. if (f) fclose(f);
  176. puts("envreg: error: Out of memory");
  177. return -1;
  178. }