Line data Source code
1 : /* TLD library -- TLD validation command line tools
2 : * Copyright (c) 2011-2018 Made to Order Software Corp. All Rights Reserved
3 : *
4 : * Permission is hereby granted, free of charge, to any person obtaining a
5 : * copy of this software and associated documentation files (the
6 : * "Software"), to deal in the Software without restriction, including
7 : * without limitation the rights to use, copy, modify, merge, publish,
8 : * distribute, sublicense, and/or sell copies of the Software, and to
9 : * permit persons to whom the Software is furnished to do so, subject to
10 : * the following conditions:
11 : *
12 : * The above copyright notice and this permission notice shall be included
13 : * in all copies or substantial portions of the Software.
14 : *
15 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 : * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 : * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 : * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 : * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 : */
23 :
24 : /** \file
25 : * \brief Command line tool to validate TLDs.
26 : *
27 : * This tool is used to verify URIs and emails on the command line and
28 : * in scripts.
29 : */
30 :
31 : #include "libtld/tld.h"
32 : #include <stdio.h>
33 : #include <stdlib.h>
34 : #include <string.h>
35 : #include <iostream>
36 :
37 : /// Number of errors so we know whether to exit with 0 or 1
38 : int err_count = 0;
39 :
40 : /// Whether the user asked for verbosity, false by default.
41 : int verbose = 0;
42 :
43 : /** \brief List of schemes that we more or less support (some schemes have extensions using the semi-colon that we do not support yet.)
44 : *
45 : * This list of schemes comes from http://en.wikipedia.org/wiki/URI_scheme and is
46 : * likely not 100% valid, but it should cover a pretty large number of schemes
47 : * expected to work with our system.
48 : *
49 : * \note
50 : * The documentation does not show you all the schemes. Check out the
51 : * source to see all the schemes currently included.
52 : */
53 : const char *schemes = "afp,adiumxtra,aw,beshare,bolo,cap,coap,crid,dns,feed,file,"
54 : "finger,fish,ftp,ftps,git,gopher,http,https,icap,imap,"
55 : "ipp,irc,irc6,ircs,mumble,mupdate,mysql,nfs,nntp,"
56 : "opaquelocktoken,pop,psql,psyc,rmi,rsync,rtmp,rtsp,rtspu,"
57 : "sftp,shttp,sieve,smb,snmp,soap.beep,soap.beeps,soldat,"
58 : "ssh,teamspeak,telnet,tftp,tip,udp,unreal,ut2004,vemmi,"
59 : "ventrilo,wais,webcal,wyciwyg,z39.50r,z39.50s";
60 :
61 : /// Hold a list of schemes as defined by the end user.
62 : char const * user_schemes = nullptr;
63 :
64 : /** \brief Check the parameter as a URI.
65 : *
66 : * This function verifies that the URI is valid.
67 : *
68 : * \param[in] uri The URI to be checked.
69 : */
70 222 : void check_uri(char const * uri)
71 : {
72 : tld_result result;
73 222 : if(strncasecmp(uri, "mailto:", 7) == 0)
74 : {
75 8 : tld_email_list mail;
76 4 : result = mail.parse(uri + 7, 0);
77 : }
78 : else
79 : {
80 : struct tld_info info;
81 218 : char const * s(user_schemes == nullptr ? schemes : user_schemes);
82 218 : result = tld_check_uri(uri, &info, s, 0);
83 : }
84 222 : if(result != TLD_RESULT_SUCCESS)
85 : {
86 4 : fprintf(stderr, "error: URI \"%s\" is not considered valid.\n", uri);
87 4 : ++err_count;
88 : }
89 222 : }
90 :
91 : /** \brief List the default schemes accepted.
92 : *
93 : * This function lists all the schemes defined in the \p schemes variable.
94 : */
95 2 : void list()
96 : {
97 736 : for(const char *s(schemes); *s != '\0'; ++s)
98 : {
99 734 : if(*s == ',')
100 : {
101 122 : printf("\n");
102 : }
103 : else
104 : {
105 612 : printf("%c", *s);
106 : }
107 : }
108 2 : printf("\n");
109 2 : exit(1);
110 : }
111 :
112 : /** \brief Print out the help of the tld tool.
113 : *
114 : * This function prints out the help information about the validate_tld tool.
115 : * The function does not return.
116 : */
117 2 : void usage()
118 : {
119 2 : printf("Usage: validate_tld [-<opts>] <uri> | <email>\n");
120 2 : printf("Where <uri> or <email> are URIs starting with a valid scheme.\n");
121 2 : printf("The <email> scheme is mailto:.\n");
122 2 : printf("Where -<opts> are:\n");
123 2 : printf(" -h | --help print out this help screen\n");
124 2 : printf(" -l | --list print the default list of schemes\n");
125 2 : printf(" -s | --schemes <list> set the list of schemes with user's defined schemes\n");
126 2 : printf(" the list is a comma separate set of scheme names\n");
127 2 : printf(" -v | --verbose request some verbosity of the tool's work\n");
128 2 : exit(1);
129 : }
130 :
131 : /** \brief The validate tools.
132 : *
133 : * The parameters can include any number of URIs and emails. The system
134 : * must be told what's what using a protocol. For emails, use the name
135 : * "mail".
136 : *
137 : * \param[in] argc Number of command line arguments passed in.
138 : * \param[in] argv The arguments passed in.
139 : *
140 : * \return The tool returns 0 on success meaning that all the URIs and emails are valid, 1 otherwise.
141 : */
142 229 : int main(int argc, char *argv[])
143 : {
144 : try
145 : {
146 229 : bool uri(false);
147 :
148 457 : for(int i(1); i < argc; ++i)
149 : {
150 233 : if(argv[i][0] == '-')
151 : {
152 11 : if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
153 : {
154 2 : usage();
155 : /*NOTREACHED*/
156 : }
157 9 : else if(strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "--list") == 0)
158 : {
159 2 : list();
160 : /*NOTREACHED*/
161 : }
162 7 : else if(strcmp(argv[i], "--version") == 0)
163 : {
164 1 : printf("%s\n", LIBTLD_VERSION);
165 1 : if(verbose)
166 : {
167 1 : printf("libtld v%s\n", tld_version());
168 : }
169 1 : exit(1);
170 : }
171 6 : else if(strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--schemes") == 0)
172 : {
173 3 : ++i;
174 3 : if(i >= argc)
175 : {
176 1 : fprintf(stderr, "error: the --schemes option requires a list of comma separated schemes.\n");
177 : }
178 3 : user_schemes = argv[i];
179 : }
180 3 : else if(strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0)
181 : {
182 3 : verbose = 1;
183 : }
184 : }
185 : else
186 : {
187 222 : uri = true;
188 222 : check_uri(argv[i]);
189 : }
190 : }
191 :
192 224 : if(!uri)
193 : {
194 2 : fprintf(stderr, "error: no URI were specified on the command line.\n");
195 2 : ++err_count;
196 : }
197 :
198 224 : return err_count > 0 ? 1 : 0;
199 : }
200 : catch(std::exception const& e) // LCOV_EXCL_LINE
201 : {
202 : // an exception occurred, print out the message and exit with an error
203 : //
204 : // note that this tool is not expecting any exception
205 : // because we only access the C interface which does
206 : // not throw
207 : //
208 : std::cerr << "exception: " << e.what() << std::endl; // LCOV_EXCL_LINE
209 : exit(1); // LCOV_EXCL_LINE
210 : }
211 687 : }
212 :
213 : // vim: ts=4 sw=4 et
|