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
|
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
|
-
+
+
-
+
-
-
+
-
+
-
+
-
+
-
+
+
+
-
+
-
-
+
+
+
-
+
+
-
-
+
+
|
/*
* Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im>
* Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im>
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
* the packaging of this file.
*
* Alternatively, it may be distributed under the terms of the GNU General
* Public License, either version 2 or 3, which can be found in the file
* LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
* file.
*/
#include "config.h"
#import "OFApplication.h"
#import "OFArray.h"
#import "OFDNSResolver.h"
#import "OFIRI.h"
#import "OFLocale.h"
#import "OFOptionsParser.h"
#import "OFSandbox.h"
#import "OFStdIOStream.h"
@interface OFDNS: OFObject <OFApplicationDelegate, OFDNSResolverQueryDelegate>
{
size_t _inFlight;
int _errors;
}
@end
OF_APPLICATION_DELEGATE(OFDNS)
static void
help(OFStream *stream, bool full, int status)
{
[OFStdErr writeLine:
[OFStdErr writeLine: OF_LOCALIZED(@"usage",
OF_LOCALIZED(@"usage",
@"Usage: %[prog] -[chst] domain1 [domain2 ...]",
@"prog", [OFApplication programName])];
if (full) {
[stream writeString: @"\n"];
[stream writeLine: OF_LOCALIZED(@"full_usage",
@"Options:\n "
@"-c --class "
@"-c --class= "
@" The DNS class to query (defaults to IN)\n "
@"-h --help "
@"-h --help "
@" Show this help\n "
@"-s --server"
@"-s --server="
@" The server to query\n "
@"-t --type "
@"-t --type= "
@" The record type to query (defaults to ALL, can be "
@"repeated)")];
@"repeated)\n "
@" --tcp "
@" Force using TCP for the query")];
}
[OFApplication terminateWithStatus: status];
}
@implementation OFDNS
- (void)resolver: (OFDNSResolver *)resolver
didPerformQuery: (OFDNSQuery *)query
response: (OFDNSResponse *)response
exception: (id)exception
{
_inFlight--;
if (exception == nil)
[OFStdOut writeFormat: @"%@\n", response];
else {
[OFStdErr writeLine: OF_LOCALIZED(
[OFStdErr writeLine: OF_LOCALIZED(@"failed_to_resolve",
@"failed_to_resolve",
@"Failed to resolve: %[exception]",
@"exception", exception)];
_errors++;
}
if (_inFlight == 0)
[OFApplication terminateWithStatus: _errors];
}
- (void)applicationDidFinishLaunching
- (void)applicationDidFinishLaunching: (OFNotification *)notification
{
OFString *DNSClassString, *server;
bool forceTCP;
const OFOptionsParserOption options[] = {
{ 'c', @"class", 1, NULL, &DNSClassString },
{ 'h', @"help", 0, NULL, NULL },
{ 's', @"server", 1, NULL, &server },
{ 't', @"type", 1, NULL, NULL },
{ '\0', @"tcp", 0, &forceTCP, NULL },
{ '\0', nil, 0, NULL, NULL }
};
OFMutableArray OF_GENERIC(OFString *) *recordTypes;
OFOptionsParser *optionsParser;
OFUnichar option;
OFArray OF_GENERIC(OFString *) *remainingArguments;
OFDNSResolver *resolver;
OFDNSClass DNSClass;
#ifdef OF_HAVE_FILES
# ifndef OF_AMIGAOS
[OFLocale addLocalizationDirectory: @LOCALIZATION_DIR];
[OFLocale addLocalizationDirectoryIRI:
[OFIRI fileIRIWithPath: @LOCALIZATION_DIR]];
# else
[OFLocale addLocalizationDirectory:
@"PROGDIR:/share/ofdns/localization"];
[OFLocale addLocalizationDirectoryIRI:
[OFIRI fileIRIWithPath: @"PROGDIR:/share/ofdns/localization"]];
# endif
#endif
#ifdef OF_HAVE_SANDBOX
OFSandbox *sandbox = [[OFSandbox alloc] init];
@try {
sandbox.allowsStdIO = true;
|