local_part_quote(uschar *lpart)
{
BOOL needs_quote = FALSE;
-int size, ptr;
-uschar *yield;
+gstring * g;
uschar *t;
for (t = lpart; !needs_quote && *t != 0; t++)
if (!needs_quote) return lpart;
-size = ptr = 0;
-yield = string_catn(NULL, &size, &ptr, US"\"", 1);
+g = string_catn(NULL, US"\"", 1);
for (;;)
{
uschar *nq = US Ustrpbrk(lpart, "\\\"");
if (nq == NULL)
{
- yield = string_cat(yield, &size, &ptr, lpart);
+ g = string_cat(g, lpart);
break;
}
- yield = string_catn(yield, &size, &ptr, lpart, nq - lpart);
- yield = string_catn(yield, &size, &ptr, US"\\", 1);
- yield = string_catn(yield, &size, &ptr, nq, 1);
+ g = string_catn(g, lpart, nq - lpart);
+ g = string_catn(g, US"\\", 1);
+ g = string_catn(g, nq, 1);
lpart = nq + 1;
}
-yield = string_catn(yield, &size, &ptr, US"\"", 1);
-yield[ptr] = 0;
-return yield;
+g = string_catn(g, US"\"", 1);
+return string_from_gstring(g);
}
get_stdinput(char *(*fn_readline)(const char *), void(*fn_addhist)(const char *))
{
int i;
-int size = 0;
-int ptr = 0;
-uschar *yield = NULL;
+gstring * g = NULL;
-if (fn_readline == NULL) { printf("> "); fflush(stdout); }
+if (!fn_readline) { printf("> "); fflush(stdout); }
for (i = 0;; i++)
{
while (p < ss && isspace(*p)) p++; /* leading space after cont */
}
- yield = string_catn(yield, &size, &ptr, p, ss - p);
+ g = string_catn(g, p, ss - p);
#ifdef USE_READLINE
- if (fn_readline != NULL) free(readline_line);
+ if (fn_readline) free(readline_line);
#endif
- /* yield can only be NULL if ss==p */
- if (ss == p || yield[ptr-1] != '\\')
- {
- if (yield) yield[ptr] = 0;
+ /* g can only be NULL if ss==p */
+ if (ss == p || g->s[g->ptr-1] != '\\')
break;
- }
- yield[--ptr] = 0;
+
+ --g->ptr;
+ (void) string_from_gstring(g);
}
-if (yield == NULL) printf("\n");
-return yield;
+if (!g) printf("\n");
+return string_from_gstring(g);
}
if (!receive_timeout)
{
- struct timeval t = { 30*60, 0 }; /* 30 minutes */
+ struct timeval t = { .tv_sec = 30*60, .tv_usec = 0 }; /* 30 minutes */
fd_set r;
FD_ZERO(&r); FD_SET(0, &r);
return 0; /* To stop compiler warning */
}
+/*************************************************
+* read as much as requested *
+*************************************************/
+
+/* The syscall read(2) doesn't always returns as much as we want. For
+several reasons it might get less. (Not talking about signals, as syscalls
+are restartable). When reading from a network or pipe connection the sender
+might send in smaller chunks, with delays between these chunks. The read(2)
+may return such a chunk.
+
+The more the writer writes and the smaller the pipe between write and read is,
+the more we get the chance of reading leass than requested. (See bug 2130)
+
+This function read(2)s until we got all the data we *requested*.
+
+Note: This function may block. Use it only if you're sure about the
+amount of data you will get.
+
+Argument:
+ fd the file descriptor to read from
+ buffer pointer to a buffer of size len
+ len the requested(!) amount of bytes
+
+Returns: the amount of bytes read
+*/
+ssize_t
+readn(int fd, void *buffer, size_t len)
+{
+ void *next = buffer;
+ void *end = buffer + len;
+
+ while (next < end)
+ {
+ ssize_t got = read(fd, next, end - next);
+
+ /* I'm not sure if there are signals that can interrupt us,
+ for now I assume the worst */
+ if (got == -1 && errno == EINTR) continue;
+ if (got <= 0) return next - buffer;
+ next += got;
+ }
+
+ return len;
+}
+
+
/* End of exim.c */