summaryrefslogtreecommitdiff
path: root/ftparchive/override.cc
blob: 93cc34e8581177d16534bf4f74120bfde2d1736b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// -*- mode: cpp; mode: fold -*-
// Description								/*{{{*/
// $Id: override.cc,v 1.2 2001/02/20 07:03:18 jgg Exp $
/* ######################################################################

   Override
   
   Store the override file.
   
   ##################################################################### */
									/*}}}*/
// Include Files							/*{{{*/
#ifdef __GNUG__
#pragma implementation "override.h"
#endif

#include "override.h"
    
#include <apt-pkg/strutl.h>
#include <apt-pkg/error.h>

#include <stdio.h>
    
#include "override.h"
									/*}}}*/

// Override::ReadOverride - Read the override file			/*{{{*/
// ---------------------------------------------------------------------
/* This parses the override file and reads it into the map */
bool Override::ReadOverride(string File,bool Source)
{
   if (File.empty() == true)
      return true;
   
   FILE *F = fopen(File.c_str(),"r");
   if (F == 0)
      return _error->Errno("fopen","Unable to open %s",File.c_str());
   
   char Line[500];
   unsigned long Counter = 0;
   while (fgets(Line,sizeof(Line),F) != 0)
   {
      Counter++;
      Item Itm;

      // Silence 
      for (char *I = Line; *I != 0; I++)
	 if (*I == '#')
	    *I = 0;

      // Strip space leading up to the package name, skip blank lines
      char *Pkg = Line;
      for (; isspace(*Pkg) && *Pkg != 0;Pkg++);
      if (Pkg == 0)
	 continue;

      // Find the package and zero..
      char *Start = Pkg;
      char *End = Pkg;
      for (; isspace(*End) == 0 && *End != 0; End++);
      if (*End == 0)
      {
	 _error->Warning("Malformed override %s line %lu #1",File.c_str(),
			 Counter);
	 continue;
      }      
      *End = 0;

      // Find the priority
      if (Source == false)
      {
	 for (End++; isspace(*End) != 0 && *End != 0; End++);
	 Start = End;
	 for (; isspace(*End) == 0 && *End != 0; End++);
	 if (*End == 0)
	 {
	    _error->Warning("Malformed override %s line %lu #2",File.c_str(),
			    Counter);
	    continue;
	 }
	 *End = 0;
	 Itm.Priority = Start;
      }
      
      // Find the Section
      for (End++; isspace(*End) != 0 && *End != 0; End++);
      Start = End;
      for (; isspace(*End) == 0 && *End != 0; End++);
      if (*End == 0)
      {
	 _error->Warning("Malformed override %s line %lu #3",File.c_str(),
			 Counter);
	 continue;
      }      
      *End = 0;
      Itm.Section = Start;

      // Source override files only have the two columns
      if (Source == true)
      {
	 Mapping[Pkg] = Itm;
	 continue;
      }
      
      // Find the =>
      for (End++; isspace(*End) != 0 && *End != 0; End++);
      if (*End != 0)
      {
	 Start = End;
	 for (; *End != 0 && (End[0] != '=' || End[1] != '>'); End++);
	 if (*End == 0 || strlen(End) < 4)
	 {
	    Itm.OldMaint = "*";
	    Itm.NewMaint = _strstrip(Start);
	 }
	 else
	 {
	    *End = 0;
	    Itm.OldMaint = _strstrip(Start);
	    
	    End += 3;
	    Itm.NewMaint = _strstrip(End);
	 }	 
      }

      Mapping[Pkg] = Itm;
   }

   if (ferror(F))
      _error->Errno("fgets","Failed to read the override file %s",File.c_str());
   fclose(F);
   return true;
}
									/*}}}*/
// Override::Item::SwapMaint - Swap the maintainer field if necessary	/*{{{*/
// ---------------------------------------------------------------------
/* Returns the new maintainer string after evaluating the rewriting rule. If
   there is a rule but it does not match then the empty string is returned,
   also if there was no rewrite rule the empty string is returned. Failed
   indicates if there was some kind of problem while rewriting. */
string Override::Item::SwapMaint(string Orig,bool &Failed)
{
   Failed = false;
   
   // Degenerate case..
   if (NewMaint.empty() == true)
	 return OldMaint;
   
   if (OldMaint == "*")
      return NewMaint;
   
   /* James: ancient, eliminate it, however it is still being used in the main
      override file. Thus it persists.*/
#if 1
   // Break OldMaint up into little bits on double slash boundaries.
   string::iterator End = OldMaint.begin();
   while (1)
   {
      string::iterator Start = End;      
      for (; End < OldMaint.end() &&
	   (End + 3 >= OldMaint.end() || End[0] != ' ' || 
	    End[1] != '/' || End[2] != '/'); End++);
      if (stringcasecmp(Start,End,Orig.begin(),Orig.end()) == 0)
	 return NewMaint;
      
      if (End >= OldMaint.end())
	 break;

      // Skip the divider and white space
      for (; End < OldMaint.end() && (*End == '/' || *End == ' '); End++);
   }
#else
   if (stringcasecmp(OldMaint.begin(),OldMaint.end(),Orig.begin(),Orig.end()) == 0)
      return NewMaint;   
#endif
   
   Failed = true;
   return string();
}
									/*}}}*/