+ FILE *f;
+ char line[8192];
+ int linenum = 0;
+ u_int kbits;
+ char *cp, *cp2, *hashed_host;
+ HostStatus end_return;
+
+ debug3("check_host_in_hostfile: filename %s", filename);
+
+ /* Open the file containing the list of known hosts. */
+ f = fopen(filename, "r");
+ if (!f)
+ return HOST_NEW;
+
+ /*
+ * Return value when the loop terminates. This is set to
+ * HOST_CHANGED if we have seen a different key for the host and have
+ * not found the proper one.
+ */
+ end_return = HOST_NEW;
+
+ /* Go through the file. */
+ while (fgets(line, sizeof(line), f)) {
+ cp = line;
+ linenum++;
+
+ /* Skip any leading whitespace, comments and empty lines. */
+ for (; *cp == ' ' || *cp == '\t'; cp++)
+ ;
+ if (!*cp || *cp == '#' || *cp == '\n')
+ continue;
+
+ /* Find the end of the host name portion. */
+ for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++)
+ ;
+
+ /* Check if the host name matches. */
+ if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) {
+ if (*cp != HASH_DELIM)
+ continue;
+ hashed_host = host_hash(host, cp, (u_int) (cp2 - cp));
+ if (hashed_host == NULL) {
+ debug("Invalid hashed host line %d of %s",
+ linenum, filename);
+ continue;
+ }
+ if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0)
+ continue;
+ }
+
+ /* Got a match. Skip host name. */
+ cp = cp2;
+
+ /*
+ * Extract the key from the line. This will skip any leading
+ * whitespace. Ignore badly formatted lines.
+ */
+ if (!hostfile_read_key(&cp, &kbits, found))
+ continue;
+
+ if (numret != NULL)
+ *numret = linenum;
+
+ if (key == NULL) {
+ /* we found a key of the requested type */
+ if (found->type == keytype) {
+ fclose(f);
+ return HOST_FOUND;
+ }
+ continue;
+ }
+
+ if (!hostfile_check_key(kbits, found, host, filename, linenum))
+ continue;
+
+ /* Check if the current key is the same as the given key. */
+ if (key_equal(key, found)) {
+ /* Ok, they match. */
+ debug3("check_host_in_hostfile: match line %d", linenum);
+ fclose(f);
+ return HOST_OK;
+ }
+ /*
+ * They do not match. We will continue to go through the
+ * file; however, we note that we will not return that it is
+ * new.
+ */
+ end_return = HOST_CHANGED;