Newer
Older
/*!
* core handler for dynamic strings.
* This is not meant to be called directly, but rather through the
* various wrapper macros
* ast_str_set(...)
* ast_str_append(...)
* ast_str_set_va(...)
* ast_str_append_va(...)
int __ast_str_helper(struct ast_str **buf, size_t max_len,
int append, const char *fmt, va_list ap)
int offset = (append && (*buf)->len) ? (*buf)->used : 0;
if (max_len < 0)
max_len = (*buf)->len; /* don't exceed the allocated space */
/*
* Ask vsnprintf how much space we need. Remember that vsnprintf
* does not count the final '\0' so we must add 1.
*/
res = vsnprintf((*buf)->str + offset, (*buf)->len - offset, fmt, ap);
/*
* If there is not enough space and we are below the max length,
* reallocate the buffer and return a message telling to retry.
*/
if (need > (*buf)->len && (max_len == 0 || (*buf)->len < max_len) ) {
if (max_len && max_len < need) /* truncate as needed */
else if (max_len == 0) /* if unbounded, give more room for next time */
need += 16 + need/4;
if (0) /* debugging */
ast_verbose("extend from %d to %d\n", (int)(*buf)->len, need);
if (ast_str_make_space(buf, need)) {
ast_verbose("failed to extend from %d to %d\n", (int)(*buf)->len, need);
return AST_DYNSTR_BUILD_FAILED;
(*buf)->str[offset] = '\0'; /* Truncate the partial write. */
Russell Bryant
committed
/* va_end() and va_start() must be done before calling
* vsnprintf() again. */
return AST_DYNSTR_BUILD_RETRY;
}
/* update space used, keep in mind the truncation */
(*buf)->used = (res + offset > (*buf)->len) ? (*buf)->len : res + offset;
void ast_enable_packet_fragmentation(int sock)
{
#if defined(HAVE_IP_MTU_DISCOVER)
int val = IP_PMTUDISC_DONT;
if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)))
ast_log(LOG_WARNING, "Unable to disable PMTU discovery. Large UDP packets may fail to be delivered when sent from this socket.\n");
#endif /* HAVE_IP_MTU_DISCOVER */
Tilghman Lesher
committed
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
int ast_mkdir(const char *path, int mode)
{
char *ptr;
int len = strlen(path), count = 0, x, piececount = 0;
char *tmp = ast_strdupa(path);
char **pieces;
char *fullpath = alloca(len + 1);
int res = 0;
for (ptr = tmp; *ptr; ptr++) {
if (*ptr == '/')
count++;
}
/* Count the components to the directory path */
pieces = alloca(count * sizeof(*pieces));
for (ptr = tmp; *ptr; ptr++) {
if (*ptr == '/') {
*ptr = '\0';
pieces[piececount++] = ptr + 1;
}
}
*fullpath = '\0';
for (x = 0; x < piececount; x++) {
/* This looks funky, but the buffer is always ideally-sized, so it's fine. */
strcat(fullpath, "/");
strcat(fullpath, pieces[x]);
res = mkdir(fullpath, mode);
if (res && errno != EEXIST)
return errno;
}
return 0;
}