override.cc 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: override.cc,v 1.4 2003/02/10 07:34:41 doogie Exp $
  4. /* ######################################################################
  5. Override
  6. Store the override file.
  7. ##################################################################### */
  8. /*}}}*/
  9. // Include Files /*{{{*/
  10. #ifdef __GNUG__
  11. #pragma implementation "override.h"
  12. #endif
  13. #include "override.h"
  14. #include <apti18n.h>
  15. #include <apt-pkg/strutl.h>
  16. #include <apt-pkg/error.h>
  17. #include <stdio.h>
  18. #include "override.h"
  19. /*}}}*/
  20. // Override::ReadOverride - Read the override file /*{{{*/
  21. // ---------------------------------------------------------------------
  22. /* This parses the override file and reads it into the map */
  23. bool Override::ReadOverride(string File,bool Source)
  24. {
  25. if (File.empty() == true)
  26. return true;
  27. FILE *F = fopen(File.c_str(),"r");
  28. if (F == 0)
  29. return _error->Errno("fopen",_("Unable to open %s"),File.c_str());
  30. char Line[500];
  31. unsigned long Counter = 0;
  32. while (fgets(Line,sizeof(Line),F) != 0)
  33. {
  34. Counter++;
  35. Item Itm;
  36. // Silence
  37. for (char *I = Line; *I != 0; I++)
  38. if (*I == '#')
  39. *I = 0;
  40. // Strip space leading up to the package name, skip blank lines
  41. char *Pkg = Line;
  42. for (; isspace(*Pkg) && *Pkg != 0;Pkg++);
  43. if (Pkg == 0)
  44. continue;
  45. // Find the package and zero..
  46. char *Start = Pkg;
  47. char *End = Pkg;
  48. for (; isspace(*End) == 0 && *End != 0; End++);
  49. if (*End == 0)
  50. {
  51. _error->Warning(_("Malformed override %s line %lu #1"),File.c_str(),
  52. Counter);
  53. continue;
  54. }
  55. *End = 0;
  56. // Find the priority
  57. if (Source == false)
  58. {
  59. for (End++; isspace(*End) != 0 && *End != 0; End++);
  60. Start = End;
  61. for (; isspace(*End) == 0 && *End != 0; End++);
  62. if (*End == 0)
  63. {
  64. _error->Warning(_("Malformed override %s line %lu #2"),File.c_str(),
  65. Counter);
  66. continue;
  67. }
  68. *End = 0;
  69. Itm.Priority = Start;
  70. }
  71. // Find the Section
  72. for (End++; isspace(*End) != 0 && *End != 0; End++);
  73. Start = End;
  74. for (; isspace(*End) == 0 && *End != 0; End++);
  75. if (*End == 0)
  76. {
  77. _error->Warning(_("Malformed override %s line %lu #3"),File.c_str(),
  78. Counter);
  79. continue;
  80. }
  81. *End = 0;
  82. Itm.FieldOverride["Section"] = Start;
  83. // Source override files only have the two columns
  84. if (Source == true)
  85. {
  86. Mapping[Pkg] = Itm;
  87. continue;
  88. }
  89. // Find the =>
  90. for (End++; isspace(*End) != 0 && *End != 0; End++);
  91. if (*End != 0)
  92. {
  93. Start = End;
  94. for (; *End != 0 && (End[0] != '=' || End[1] != '>'); End++);
  95. if (*End == 0 || strlen(End) < 4)
  96. {
  97. Itm.OldMaint = "*";
  98. Itm.NewMaint = _strstrip(Start);
  99. }
  100. else
  101. {
  102. *End = 0;
  103. Itm.OldMaint = _strstrip(Start);
  104. End += 3;
  105. Itm.NewMaint = _strstrip(End);
  106. }
  107. }
  108. Mapping[Pkg] = Itm;
  109. }
  110. if (ferror(F))
  111. _error->Errno("fgets",_("Failed to read the override file %s"),File.c_str());
  112. fclose(F);
  113. return true;
  114. }
  115. /*}}}*/
  116. // Override::ReadExtraOverride - Read the extra override file /*{{{*/
  117. // ---------------------------------------------------------------------
  118. /* This parses the extra override file and reads it into the map */
  119. bool Override::ReadExtraOverride(string File,bool Source)
  120. {
  121. if (File.empty() == true)
  122. return true;
  123. FILE *F = fopen(File.c_str(),"r");
  124. if (F == 0)
  125. return _error->Errno("fopen",_("Unable to open %s"),File.c_str());
  126. char Line[500];
  127. unsigned long Counter = 0;
  128. while (fgets(Line,sizeof(Line),F) != 0)
  129. {
  130. Counter++;
  131. // Silence
  132. for (char *I = Line; *I != 0; I++)
  133. if (*I == '#')
  134. *I = 0;
  135. // Strip space leading up to the package name, skip blank lines
  136. char *Pkg = Line;
  137. for (; isspace(*Pkg) && *Pkg != 0;Pkg++);
  138. if (Pkg == 0)
  139. continue;
  140. // Find the package and zero..
  141. char *End = Pkg;
  142. for (; isspace(*End) == 0 && *End != 0; End++);
  143. if (*End == 0)
  144. {
  145. _error->Warning(_("Malformed override %s line %lu #1"),File.c_str(),
  146. Counter);
  147. continue;
  148. }
  149. *End = 0;
  150. // Find the field
  151. for (End++; isspace(*End) != 0 && *End != 0; End++);
  152. char *Field = End;
  153. for (; isspace(*End) == 0 && *End != 0; End++);
  154. if (*End == 0)
  155. {
  156. _error->Warning(_("Malformed override %s line %lu #2"),File.c_str(),
  157. Counter);
  158. continue;
  159. }
  160. *End = 0;
  161. // Find the field value
  162. for (End++; isspace(*End) != 0 && *End != 0; End++);
  163. char *Value = End;
  164. for (; *End != 0; End++);
  165. for (; isspace(*(End-1)) && End > Value; End--);
  166. if (End == Value)
  167. {
  168. _error->Warning(_("Malformed override %s line %lu #3"),File.c_str(),
  169. Counter);
  170. continue;
  171. }
  172. *End = 0;
  173. Mapping[Pkg].FieldOverride[Field] = Value;
  174. }
  175. if (ferror(F))
  176. _error->Errno("fgets",_("Failed to read the override file %s"),File.c_str());
  177. fclose(F);
  178. return true;
  179. }
  180. /*}}}*/
  181. // Override::GetItem - Get a architecture specific item /*{{{*/
  182. // ---------------------------------------------------------------------
  183. /* Returns a override item for the given package and the given architecture.
  184. * Treats "all" special
  185. */
  186. Override::Item* Override::GetItem(string Package, string Architecture)
  187. {
  188. map<string,Item>::iterator I = Mapping.find(Package);
  189. map<string,Item>::iterator J = Mapping.find(Package + "/" + Architecture);
  190. if (I == Mapping.end() && J == Mapping.end())
  191. {
  192. return 0;
  193. }
  194. Item *result = new Item;
  195. if (I == Mapping.end()) *result = J->second;
  196. else
  197. {
  198. *result = I->second;
  199. if (J != Mapping.end())
  200. {
  201. Item *R = &J->second;
  202. if (R->Priority != "") result->Priority = R->Priority;
  203. if (R->OldMaint != "") result->OldMaint = R->OldMaint;
  204. if (R->NewMaint != "") result->NewMaint = R->NewMaint;
  205. for (map<string,string>::iterator foI = R->FieldOverride.begin();
  206. foI != R->FieldOverride.end(); foI++)
  207. {
  208. result->FieldOverride[foI->first] = foI->second;
  209. }
  210. }
  211. }
  212. return result;
  213. };
  214. // Override::Item::SwapMaint - Swap the maintainer field if necessary /*{{{*/
  215. // ---------------------------------------------------------------------
  216. /* Returns the new maintainer string after evaluating the rewriting rule. If
  217. there is a rule but it does not match then the empty string is returned,
  218. also if there was no rewrite rule the empty string is returned. Failed
  219. indicates if there was some kind of problem while rewriting. */
  220. string Override::Item::SwapMaint(string Orig,bool &Failed)
  221. {
  222. Failed = false;
  223. // Degenerate case..
  224. if (NewMaint.empty() == true)
  225. return OldMaint;
  226. if (OldMaint == "*")
  227. return NewMaint;
  228. /* James: ancient, eliminate it, however it is still being used in the main
  229. override file. Thus it persists.*/
  230. #if 1
  231. // Break OldMaint up into little bits on double slash boundaries.
  232. string::iterator End = OldMaint.begin();
  233. while (1)
  234. {
  235. string::iterator Start = End;
  236. for (; End < OldMaint.end() &&
  237. (End + 3 >= OldMaint.end() || End[0] != ' ' ||
  238. End[1] != '/' || End[2] != '/'); End++);
  239. if (stringcasecmp(Start,End,Orig.begin(),Orig.end()) == 0)
  240. return NewMaint;
  241. if (End >= OldMaint.end())
  242. break;
  243. // Skip the divider and white space
  244. for (; End < OldMaint.end() && (*End == '/' || *End == ' '); End++);
  245. }
  246. #else
  247. if (stringcasecmp(OldMaint.begin(),OldMaint.end(),Orig.begin(),Orig.end()) == 0)
  248. return NewMaint;
  249. #endif
  250. Failed = true;
  251. return string();
  252. }
  253. /*}}}*/