FILE *fp;
char pgpassfile[MAXPGPATH];
struct stat stat_buf;
-
-#define LINELEN NAMEDATALEN*5
- char buf[LINELEN];
+ PQExpBufferData buf;
if (dbname == NULL || strlen(dbname) == 0)
return NULL;
if (fp == NULL)
return NULL;
+ /* Use an expansible buffer to accommodate any reasonable line length */
+ initPQExpBuffer(&buf);
+
while (!feof(fp) && !ferror(fp))
{
- char *t = buf,
- *ret,
- *p1,
- *p2;
- int len;
+ /* Make sure there's a reasonable amount of room in the buffer */
+ if (!enlargePQExpBuffer(&buf, 128))
+ break;
- if (fgets(buf, sizeof(buf), fp) == NULL)
+ /* Read some data, appending it to what we already have */
+ if (fgets(buf.data + buf.len, buf.maxlen - buf.len, fp) == NULL)
break;
+ buf.len += strlen(buf.data + buf.len);
- len = strlen(buf);
+ /* If we don't yet have a whole line, loop around to read more */
+ if (!(buf.len > 0 && buf.data[buf.len - 1] == '\n') && !feof(fp))
+ continue;
- /* Remove trailing newline */
- if (len > 0 && buf[len - 1] == '\n')
+ /* ignore comments */
+ if (buf.data[0] != '#')
{
- buf[--len] = '\0';
- /* Handle DOS-style line endings, too, even when not on Windows */
- if (len > 0 && buf[len - 1] == '\r')
- buf[--len] = '\0';
- }
+ char *t = buf.data;
+ int len = buf.len;
- if (len == 0)
- continue;
+ /* Remove trailing newline */
+ if (len > 0 && t[len - 1] == '\n')
+ {
+ t[--len] = '\0';
+ /* Handle DOS-style line endings, too */
+ if (len > 0 && t[len - 1] == '\r')
+ t[--len] = '\0';
+ }
- if ((t = pwdfMatchesString(t, hostname)) == NULL ||
- (t = pwdfMatchesString(t, port)) == NULL ||
- (t = pwdfMatchesString(t, dbname)) == NULL ||
- (t = pwdfMatchesString(t, username)) == NULL)
- continue;
+ if (len > 0 &&
+ (t = pwdfMatchesString(t, hostname)) != NULL &&
+ (t = pwdfMatchesString(t, port)) != NULL &&
+ (t = pwdfMatchesString(t, dbname)) != NULL &&
+ (t = pwdfMatchesString(t, username)) != NULL)
+ {
+ /* Found a match. */
+ char *ret,
+ *p1,
+ *p2;
- /* Found a match. */
- ret = strdup(t);
- fclose(fp);
+ ret = strdup(t);
- if (!ret)
- {
- /* Out of memory. XXX: an error message would be nice. */
- return NULL;
- }
+ fclose(fp);
+ termPQExpBuffer(&buf);
- /* De-escape password. */
- for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
- {
- if (*p1 == '\\' && p1[1] != '\0')
- ++p1;
- *p2 = *p1;
+ if (!ret)
+ {
+ /* Out of memory. XXX: an error message would be nice. */
+ return NULL;
+ }
+
+ /* De-escape password. */
+ for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
+ {
+ if (*p1 == '\\' && p1[1] != '\0')
+ ++p1;
+ *p2 = *p1;
+ }
+ *p2 = '\0';
+
+ return ret;
+ }
}
- *p2 = '\0';
- return ret;
+ /* No match, reset buffer to prepare for next line. */
+ buf.len = 0;
}
fclose(fp);
+ termPQExpBuffer(&buf);
return NULL;
-
-#undef LINELEN
}