+3707. [bug] irs_resconf_load now returns ISC_R_FILENOTFOUND
+ on a missing resolv.conf file and initializes the
+ structure as if it had been configured with:
+
+ nameserver ::1
+ nameserver 127.0.0.1
+
+ Note: Callers will need to be updated to treat
+ ISC_R_FILENOTFOUND as a qualified success or else
+ they will leak memory. The following code fragment
+ will work with both only and new versions without
+ changing the behaviour of the existing code.
+
+ resconf = NULL;
+ result = irs_resconf_load(mctx, "/etc/resolv.conf",
+ &resconf);
+ if (result != ISC_SUCCESS) {
+ if (resconf != NULL)
+ irs_resconf_destroy(&resconf);
+ ....
+ }
+
+ [RT #35194]
+
3706. [contrib] queryperf: Fixed a possible integer overflow when
printing results. [RT #35182]
irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp);
/*%<
* Load the resolver configuration file 'filename' in the "resolv.conf" format,
- * and create a new irs_resconf_t object from the configuration.
+ * and create a new irs_resconf_t object from the configuration. If the file
+ * is not found ISC_R_FILENOTFOUND is returned with the structure initialized
+ * as if file contained only:
+ *
+ * nameserver ::1
+ * nameserver 127.0.0.1
*
* Notes:
*
* In addition, 'sortlist' is not actually effective; it's parsed, but
* the application cannot use the configuration.
*
+ * Returns:
+ * \li ISC_R_SUCCESS on success
+ * \li ISC_R_FILENOTFOUND if the file was not found. *confp will be valid.
+ * \li other on error.
+ *
* Requires:
*
*\li 'mctx' is a valid memory context.
conf->search[i] = NULL;
errno = 0;
- if ((fp = fopen(filename, "r")) == NULL) {
- isc_mem_put(mctx, conf, sizeof(*conf));
- return (ISC_R_INVALIDFILE);
- }
-
- ret = ISC_R_SUCCESS;
- do {
- stopchar = getword(fp, word, sizeof(word));
- if (stopchar == EOF) {
- rval = ISC_R_SUCCESS;
- POST(rval);
- break;
- }
-
- if (strlen(word) == 0U)
- rval = ISC_R_SUCCESS;
- else if (strcmp(word, "nameserver") == 0)
- rval = resconf_parsenameserver(conf, fp);
- else if (strcmp(word, "domain") == 0)
- rval = resconf_parsedomain(conf, fp);
- else if (strcmp(word, "search") == 0)
- rval = resconf_parsesearch(conf, fp);
- else if (strcmp(word, "sortlist") == 0)
- rval = resconf_parsesortlist(conf, fp);
- else if (strcmp(word, "options") == 0)
- rval = resconf_parseoption(conf, fp);
- else {
- /* unrecognised word. Ignore entire line */
- rval = ISC_R_SUCCESS;
- stopchar = eatline(fp);
+ if ((fp = fopen(filename, "r")) != NULL) {
+ ret = ISC_R_SUCCESS;
+ do {
+ stopchar = getword(fp, word, sizeof(word));
if (stopchar == EOF) {
+ rval = ISC_R_SUCCESS;
+ POST(rval);
break;
}
- }
- if (ret == ISC_R_SUCCESS && rval != ISC_R_SUCCESS)
- ret = rval;
- } while (1);
- fclose(fp);
+ if (strlen(word) == 0U)
+ rval = ISC_R_SUCCESS;
+ else if (strcmp(word, "nameserver") == 0)
+ rval = resconf_parsenameserver(conf, fp);
+ else if (strcmp(word, "domain") == 0)
+ rval = resconf_parsedomain(conf, fp);
+ else if (strcmp(word, "search") == 0)
+ rval = resconf_parsesearch(conf, fp);
+ else if (strcmp(word, "sortlist") == 0)
+ rval = resconf_parsesortlist(conf, fp);
+ else if (strcmp(word, "options") == 0)
+ rval = resconf_parseoption(conf, fp);
+ else {
+ /* unrecognised word. Ignore entire line */
+ rval = ISC_R_SUCCESS;
+ stopchar = eatline(fp);
+ if (stopchar == EOF) {
+ break;
+ }
+ }
+ if (ret == ISC_R_SUCCESS && rval != ISC_R_SUCCESS)
+ ret = rval;
+ } while (1);
+
+ fclose(fp);
+ } else {
+ switch (errno) {
+ case ENOENT:
+ break;
+ default:
+ isc_mem_put(mctx, conf, sizeof(*conf));
+ return (ISC_R_INVALIDFILE);
+ }
+ }
/* If we don't find a nameserver fall back to localhost */
if (conf->numns == 0) {
if (ret != ISC_R_SUCCESS)
irs_resconf_destroy(&conf);
- else
+ else {
+ if (fp == NULL)
+ ret = ISC_R_FILENOTFOUND;
*confp = conf;
+ }
return (ret);
}