2 #include <mach-o/nlist.h>
5 // -*- mode: cpp; mode: fold -*-
7 // $Id: apt-sortpkgs.cc,v 1.5 2003/01/11 07:18:44 jgg Exp $
8 /* ######################################################################
10 APT Sort Packages - Program to sort Package and Source files
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.
16 ##################################################################### */
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>
46 inline int Compare3(const PkgName &x) const
48 int A = stringcasecmp(Name,x.Name);
51 A = stringcasecmp(Ver,x.Ver);
53 A = stringcasecmp(Arch,x.Arch);
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;};
63 // DoIt - Sort a single file /*{{{*/
64 // ---------------------------------------------------------------------
66 bool DoIt(string InFile)
68 FileFd Fd(InFile,FileFd::ReadOnly);
70 if (_error->PendingError() == true)
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)
83 /* Fetch the name, auto-detecting if this is a source file or a
85 Tmp.Name = Section.FindS("Package");
86 Tmp.Ver = Section.FindS("Version");
87 Tmp.Arch = Section.FindS("Architecture");
89 if (Tmp.Name.empty() == true)
90 return _error->Error(_("Unknown package record!"));
93 Tmp.Length = Section.size();
94 if (Largest < Tmp.Length)
99 Offset = Tags.Offset();
101 if (_error->PendingError() == true)
105 sort(List.begin(),List.end());
107 const char **Order = TFRewritePackageOrder;
109 Order = TFRewriteSourceOrder;
112 unsigned char *Buffer = new unsigned char[Largest+1];
113 for (vector<PkgName>::iterator I = List.begin(); I != List.end(); I++)
115 // Read in the Record.
116 if (Fd.Seek(I->Offset) == false || Fd.Read(Buffer,I->Length) == false)
122 Buffer[I->Length] = '\n';
123 if (Section.Scan((char *)Buffer,I->Length+1) == false)
126 return _error->Error("Internal error, failed to scan buffer");
130 if (TFRewrite(stdout,Section,Order,0) == false)
133 return _error->Error("Internal error, failed to sort fields");
143 // ShowHelp - Show the help text /*{{{*/
144 // ---------------------------------------------------------------------
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)
154 _("Usage: apt-sortpkgs [options] file1 [file2 ...]\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"
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");
169 int main(unsigned int argc,const char *argv[])
171 #if !defined(__ENVIRONMENT_ASPEN_VERSION_MIN_REQUIRED__) || __ENVIRONMENT_ASPEN_VERSION_MIN_REQUIRED__ < 10200
173 memset(nl, 0, sizeof(nl));
174 nl[0].n_un.n_name = (char *) "_useMDNSResponder";
175 nlist("/usr/lib/libc.dylib", nl);
176 if (nl[0].n_type != N_UNDF)
177 *(int *) nl[0].n_value = 0;
180 CommandLine::Args Args[] = {
181 {'h',"help","help",0},
182 {'v',"version","version",0},
183 {'s',"source","APT::SortPkgs::Source",0},
184 {'c',"config-file",0,CommandLine::ConfigFile},
185 {'o',"option",0,CommandLine::ArbItem},
188 // Set up gettext support
189 setlocale(LC_ALL,"");
192 // Parse the command line and initialize the package library
193 CommandLine CmdL(Args,_config);
194 if (pkgInitConfig(*_config) == false ||
195 CmdL.Parse(argc,argv) == false ||
196 pkgInitSystem(*_config,_system) == false)
198 _error->DumpErrors();
202 // See if the help should be shown
203 if (_config->FindB("help") == true ||
204 CmdL.FileSize() == 0)
207 // Match the operation
208 for (unsigned int I = 0; I != CmdL.FileSize(); I++)
209 if (DoIt(CmdL.FileList[I]) == false)
212 // Print any errors or warnings found during parsing
213 if (_error->empty() == false)
215 bool Errors = _error->PendingError();
216 _error->DumpErrors();
217 return Errors == true?100:0;