]> git.saurik.com Git - apt-legacy.git/blob - cmdline/apt-sortpkgs.cc.orig
Drastic, sweeping modifications to support iPhone 1.2.0/2.0.
[apt-legacy.git] / cmdline / apt-sortpkgs.cc.orig
1 extern "C" {
2 #include <mach-o/nlist.h>
3 }
4
5 // -*- mode: cpp; mode: fold -*-
6 // Description /*{{{*/
7 // $Id: apt-sortpkgs.cc,v 1.5 2003/01/11 07:18:44 jgg Exp $
8 /* ######################################################################
9
10 APT Sort Packages - Program to sort Package and Source files
11
12 This program is quite simple, it just sorts the package files by
13 package and sorts the fields inside by the internal APT sort order.
14 Input is taken from a named file and sent to stdout.
15
16 ##################################################################### */
17 /*}}}*/
18 // Include Files /*{{{*/
19 #include <apt-pkg/tagfile.h>
20 #include <apt-pkg/error.h>
21 #include <apt-pkg/configuration.h>
22 #include <apt-pkg/cmndline.h>
23 #include <apt-pkg/init.h>
24 #include <apt-pkg/strutl.h>
25
26 #include <config.h>
27 #include <apti18n.h>
28
29 #include <vector>
30 #include <algorithm>
31
32 #include <locale.h>
33 #include <unistd.h>
34 /*}}}*/
35
36 using namespace std;
37
38 struct PkgName
39 {
40 string Name;
41 string Ver;
42 string Arch;
43 unsigned long Offset;
44 unsigned long Length;
45
46 inline int Compare3(const PkgName &x) const
47 {
48 int A = stringcasecmp(Name,x.Name);
49 if (A == 0)
50 {
51 A = stringcasecmp(Ver,x.Ver);
52 if (A == 0)
53 A = stringcasecmp(Arch,x.Arch);
54 }
55 return A;
56 }
57
58 bool operator <(const PkgName &x) const {return Compare3(x) < 0;};
59 bool operator >(const PkgName &x) const {return Compare3(x) > 0;};
60 bool operator ==(const PkgName &x) const {return Compare3(x) == 0;};
61 };
62
63 // DoIt - Sort a single file /*{{{*/
64 // ---------------------------------------------------------------------
65 /* */
66 bool DoIt(string InFile)
67 {
68 FileFd Fd(InFile,FileFd::ReadOnly);
69 pkgTagFile Tags(&Fd);
70 if (_error->PendingError() == true)
71 return false;
72
73 // Parse.
74 vector<PkgName> List;
75 pkgTagSection Section;
76 unsigned long Largest = 0;
77 unsigned long Offset = Tags.Offset();
78 bool Source = _config->FindB("APT::SortPkgs::Source",false);
79 while (Tags.Step(Section) == true)
80 {
81 PkgName Tmp;
82
83 /* Fetch the name, auto-detecting if this is a source file or a
84 package file */
85 Tmp.Name = Section.FindS("Package");
86 Tmp.Ver = Section.FindS("Version");
87 Tmp.Arch = Section.FindS("Architecture");
88
89 if (Tmp.Name.empty() == true)
90 return _error->Error(_("Unknown package record!"));
91
92 Tmp.Offset = Offset;
93 Tmp.Length = Section.size();
94 if (Largest < Tmp.Length)
95 Largest = Tmp.Length;
96
97 List.push_back(Tmp);
98
99 Offset = Tags.Offset();
100 }
101 if (_error->PendingError() == true)
102 return false;
103
104 // Sort it
105 sort(List.begin(),List.end());
106
107 const char **Order = TFRewritePackageOrder;
108 if (Source == true)
109 Order = TFRewriteSourceOrder;
110
111 // Emit
112 unsigned char *Buffer = new unsigned char[Largest+1];
113 for (vector<PkgName>::iterator I = List.begin(); I != List.end(); I++)
114 {
115 // Read in the Record.
116 if (Fd.Seek(I->Offset) == false || Fd.Read(Buffer,I->Length) == false)
117 {
118 delete [] Buffer;
119 return false;
120 }
121
122 Buffer[I->Length] = '\n';
123 if (Section.Scan((char *)Buffer,I->Length+1) == false)
124 {
125 delete [] Buffer;
126 return _error->Error("Internal error, failed to scan buffer");
127 }
128
129 // Sort the section
130 if (TFRewrite(stdout,Section,Order,0) == false)
131 {
132 delete [] Buffer;
133 return _error->Error("Internal error, failed to sort fields");
134 }
135
136 fputc('\n',stdout);
137 }
138
139 delete [] Buffer;
140 return true;
141 }
142 /*}}}*/
143 // ShowHelp - Show the help text /*{{{*/
144 // ---------------------------------------------------------------------
145 /* */
146 int ShowHelp()
147 {
148 ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
149 COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
150 if (_config->FindB("version") == true)
151 return 0;
152
153 cout <<
154 _("Usage: apt-sortpkgs [options] file1 [file2 ...]\n"
155 "\n"
156 "apt-sortpkgs is a simple tool to sort package files. The -s option is used\n"
157 "to indicate what kind of file it is.\n"
158 "\n"
159 "Options:\n"
160 " -h This help text\n"
161 " -s Use source file sorting\n"
162 " -c=? Read this configuration file\n"
163 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n");
164
165 return 0;
166 }
167 /*}}}*/
168
169 int main(unsigned int argc,const char *argv[])
170 {
171 struct nlist nl[2];
172 memset(nl, 0, sizeof(nl));
173 nl[0].n_un.n_name = (char *) "_useMDNSResponder";
174 nlist("/usr/lib/libc.dylib", nl);
175 if (nl[0].n_type != N_UNDF)
176 *(int *) nl[0].n_value = 0;
177
178 CommandLine::Args Args[] = {
179 {'h',"help","help",0},
180 {'v',"version","version",0},
181 {'s',"source","APT::SortPkgs::Source",0},
182 {'c',"config-file",0,CommandLine::ConfigFile},
183 {'o',"option",0,CommandLine::ArbItem},
184 {0,0,0,0}};
185
186 // Set up gettext support
187 setlocale(LC_ALL,"");
188 textdomain(PACKAGE);
189
190 // Parse the command line and initialize the package library
191 CommandLine CmdL(Args,_config);
192 if (pkgInitConfig(*_config) == false ||
193 CmdL.Parse(argc,argv) == false ||
194 pkgInitSystem(*_config,_system) == false)
195 {
196 _error->DumpErrors();
197 return 100;
198 }
199
200 // See if the help should be shown
201 if (_config->FindB("help") == true ||
202 CmdL.FileSize() == 0)
203 return ShowHelp();
204
205 // Match the operation
206 for (unsigned int I = 0; I != CmdL.FileSize(); I++)
207 if (DoIt(CmdL.FileList[I]) == false)
208 break;
209
210 // Print any errors or warnings found during parsing
211 if (_error->empty() == false)
212 {
213 bool Errors = _error->PendingError();
214 _error->DumpErrors();
215 return Errors == true?100:0;
216 }
217
218 return 0;
219 }