354 static int env_read(
struct ast_channel *chan,
const char *cmd,
char *data,
355 char *buf,
size_t len)
370 static int env_write(
struct ast_channel *chan,
const char *cmd,
char *data,
373 if (!ast_strlen_zero(data) && strncmp(data,
"AST_", 4)) {
374 if (!ast_strlen_zero(value)) {
375 setenv(data, value, 1);
384 static int stat_read(
struct ast_channel *chan,
const char *cmd,
char *data,
385 char *buf,
size_t len)
392 action = strsep(&data,
",");
393 if (stat(data, &s)) {
401 snprintf(buf, len,
"%u", (
unsigned int) s.st_size);
404 snprintf(buf, len,
"%d", S_ISREG(s.st_mode) ? 1 : 0);
407 snprintf(buf, len,
"%d", S_ISDIR(s.st_mode) ? 1 : 0);
410 snprintf(buf, len,
"%d", (
int) s.st_mtime);
413 snprintf(buf, len,
"%d", (
int) s.st_mtime);
416 snprintf(buf, len,
"%d", (
int) s.st_ctime);
419 snprintf(buf, len,
"%o", (
unsigned int) s.st_mode);
434 static int64_t count_lines(
const char *filename,
enum file_format newline_format)
440 if (!(ff = fopen(filename,
"r"))) {
441 ast_log(LOG_ERROR,
"Unable to open '%s': %s\n", filename, strerror(errno));
445 while (fgets(fbuf,
sizeof(fbuf), ff)) {
446 char *next = fbuf, *first_cr = NULL, *first_nl = NULL;
451 if (newline_format == FF_DOS || newline_format == FF_MAC || newline_format == FF_UNKNOWN) {
452 first_cr = strchr(next,
'\r');
454 if (newline_format == FF_UNIX || newline_format == FF_UNKNOWN) {
455 first_nl = strchr(next,
'\n');
459 if (!first_cr && !first_nl) {
463 if (newline_format == FF_UNKNOWN) {
464 if ((first_cr && !first_nl) || (first_cr && first_cr < first_nl)) {
465 if (first_nl && first_nl == first_cr + 1) {
466 newline_format = FF_DOS;
467 }
else if (first_cr && first_cr == &fbuf[
sizeof(fbuf) - 2]) {
469 fseek(ff, -1, SEEK_CUR);
472 newline_format = FF_MAC;
476 newline_format = FF_UNIX;
482 if (newline_format == FF_DOS) {
483 if (first_nl && first_cr && first_nl == first_cr + 1) {
486 }
else if (first_cr == &fbuf[
sizeof(fbuf) - 2]) {
488 fseek(ff, -1, SEEK_CUR);
491 }
else if (newline_format == FF_MAC) {
496 }
else if (newline_format == FF_UNIX) {
509 static int file_count_line(
struct ast_channel *chan,
const char *cmd,
char *data,
struct ast_str **buf, ssize_t len)
511 enum file_format newline_format = FF_UNKNOWN;
520 if (tolower(args.format[0]) ==
'd') {
521 newline_format = FF_DOS;
522 }
else if (tolower(args.format[0]) ==
'm') {
523 newline_format = FF_MAC;
524 }
else if (tolower(args.format[0]) ==
'u') {
525 newline_format = FF_UNIX;
529 count = count_lines(args.filename, newline_format);
534 #define LINE_COUNTER(cptr, term, counter) \
535 if (*cptr == '\n' && term == FF_UNIX) { \
537 } else if (*cptr == '\n' && term == FF_DOS && dos_state == 0) { \
539 } else if (*cptr == '\r' && term == FF_DOS && dos_state == 1) { \
542 } else if (*cptr == '\r' && term == FF_MAC) { \
544 } else if (term == FF_DOS) { \
548 static enum file_format file2format(
const char *filename)
552 char *first_cr, *first_nl;
553 enum file_format newline_format = FF_UNKNOWN;
555 if (!(ff = fopen(filename,
"r"))) {
556 ast_log(LOG_ERROR,
"Cannot open '%s': %s\n", filename, strerror(errno));
560 while (fgets(fbuf,
sizeof(fbuf), ff)) {
561 first_cr = strchr(fbuf,
'\r');
562 first_nl = strchr(fbuf,
'\n');
564 if (!first_cr && !first_nl) {
568 if ((first_cr && !first_nl) || (first_cr && first_cr < first_nl)) {
570 if (first_nl && first_nl == first_cr + 1) {
571 newline_format = FF_DOS;
572 }
else if (first_cr && first_cr == &fbuf[
sizeof(fbuf) - 2]) {
574 fseek(ff, -1, SEEK_CUR);
577 newline_format = FF_MAC;
580 newline_format = FF_UNIX;
585 return newline_format;
588 static int file_format(
struct ast_channel *chan,
const char *cmd,
char *data,
struct ast_str **buf, ssize_t len)
590 enum file_format newline_format = file2format(data);
591 ast_str_set(buf, len,
"%c", newline_format == FF_UNIX ?
'u' : newline_format == FF_DOS ?
'd' : newline_format == FF_MAC ?
'm' :
'x');
595 static int file_dirname(
struct ast_channel *chan,
const char *cmd,
char *data,
char *buf,
size_t len)
612 static int file_basename(
struct ast_channel *chan,
const char *cmd,
char *data,
char *buf,
size_t len)
619 ret = basename(data);
629 static int file_read(
struct ast_channel *chan,
const char *cmd,
char *data,
struct ast_str **buf, ssize_t len)
632 int64_t offset = 0, length = LLONG_MAX;
633 enum file_format format = FF_UNKNOWN;
636 int64_t offset_offset = -1, length_offset = -1;
649 sscanf(args.offset,
"%" SCNd64, &offset);
652 sscanf(args.length,
"%" SCNd64, &length);
655 if (args.argc < 4 || !strchr(args.options,
'l')) {
659 if (!(ff = fopen(args.filename,
"r"))) {
660 ast_log(LOG_WARNING,
"Cannot open file '%s' for reading: %s\n", args.filename, strerror(errno));
664 if (fseeko(ff, 0, SEEK_END) < 0) {
665 ast_log(LOG_ERROR,
"Cannot seek to end of '%s': %s\n", args.filename, strerror(errno));
669 flength = ftello(ff);
672 fseeko(ff, offset, SEEK_END);
673 if ((offset = ftello(ff)) < 0) {
674 ast_log(AST_LOG_ERROR,
"Cannot determine offset position of '%s': %s\n", args.filename, strerror(errno));
680 fseeko(ff, length, SEEK_END);
681 if ((length = ftello(ff)) - offset < 0) {
686 }
else if (length == LLONG_MAX) {
687 fseeko(ff, 0, SEEK_END);
693 fseeko(ff, offset, SEEK_SET);
694 for (off_i = ftello(ff); off_i < flength && off_i < offset + length; off_i +=
sizeof(fbuf)) {
696 size_t toappend =
sizeof(fbuf);
698 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
699 ast_log(LOG_ERROR,
"Short read?!!\n");
704 if (off_i + toappend > offset + length) {
705 toappend = MIN(offset + length - off_i, flength - off_i);
715 if (args.argc == 5) {
716 if (tolower(args.fileformat[0]) ==
'd') {
718 }
else if (tolower(args.fileformat[0]) ==
'm') {
720 }
else if (tolower(args.fileformat[0]) ==
'u') {
725 if (format == FF_UNKNOWN) {
726 if ((format = file2format(args.filename)) == FF_UNKNOWN) {
727 ast_log(LOG_WARNING,
"'%s' is not a line-based file\n", args.filename);
732 if (offset < 0 && length <= offset) {
735 }
else if (offset == 0) {
739 if (!(ff = fopen(args.filename,
"r"))) {
740 ast_log(LOG_ERROR,
"Cannot open '%s': %s\n", args.filename, strerror(errno));
744 if (fseek(ff, 0, SEEK_END)) {
745 ast_log(LOG_ERROR,
"Cannot seek to end of file '%s': %s\n", args.filename, strerror(errno));
750 flength = ftello(ff);
752 if (length == LLONG_MAX) {
753 length_offset = flength;
757 if (offset < 0 || length < 0) {
761 for (i = (flength /
sizeof(fbuf)) *
sizeof(fbuf); i >= 0; i -=
sizeof(fbuf)) {
764 if (fseeko(ff, i, SEEK_SET)) {
765 ast_log(LOG_ERROR,
"Cannot seek to offset %" PRId64
": %s\n", i, strerror(errno));
767 end = fread(fbuf, 1,
sizeof(fbuf), ff);
768 for (pos = (end <
sizeof(fbuf) ? fbuf + end - 1 : fbuf +
sizeof(fbuf) - 1); pos >= fbuf; pos--) {
769 LINE_COUNTER(pos, format, count);
771 if (length < 0 && count * -1 == length) {
772 length_offset = i + (pos - fbuf);
773 }
else if (offset < 0 && count * -1 == (offset - 1)) {
775 if (format == FF_DOS) {
776 offset_offset = i + (pos - fbuf) + 2;
778 offset_offset = i + (pos - fbuf) + 1;
783 if ((offset < 0 && offset_offset >= 0) || (offset >= 0 && length_offset >= 0)) {
788 if (offset < 0 && offset_offset < 0 && offset == count * -1) {
796 fseek(ff, 0, SEEK_SET);
797 for (i = 0; i < flength; i +=
sizeof(fbuf)) {
799 if (i +
sizeof(fbuf) <= flength) {
801 memset(fbuf, 0,
sizeof(fbuf));
803 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
804 ast_log(LOG_ERROR,
"Short read?!!\n");
808 for (pos = fbuf; pos < fbuf +
sizeof(fbuf); pos++) {
809 LINE_COUNTER(pos, format, count);
811 if (count == offset) {
812 offset_offset = i + (pos - fbuf) + 1;
816 if (offset_offset >= 0) {
822 if (offset_offset < 0) {
823 ast_log(LOG_ERROR,
"Offset '%s' refers to before the beginning of the file!\n", args.offset);
829 if (fseeko(ff, offset_offset, SEEK_SET)) {
830 ast_log(LOG_ERROR,
"fseeko failed: %s\n", strerror(errno));
837 if (length_offset >= 0) {
838 ast_debug(3,
"offset=%" PRId64
", length=%" PRId64
", offset_offset=%" PRId64
", length_offset=%" PRId64
"\n", offset, length, offset_offset, length_offset);
839 for (i = offset_offset; i < length_offset; i +=
sizeof(fbuf)) {
840 if (fread(fbuf, 1, i +
sizeof(fbuf) > flength ? flength - i :
sizeof(fbuf), ff) < (i +
sizeof(fbuf) > flength ? flength - i :
sizeof(fbuf))) {
841 ast_log(LOG_ERROR,
"Short read?!!\n");
843 ast_debug(3,
"Appending first %" PRId64
" bytes of fbuf=%s\n", (int64_t)(i +
sizeof(fbuf) > length_offset ? length_offset - i :
sizeof(fbuf)), fbuf);
844 ast_str_append_substr(buf, len, fbuf, i +
sizeof(fbuf) > length_offset ? length_offset - i :
sizeof(fbuf));
846 }
else if (length == 0) {
850 int64_t current_length = 0;
852 ast_debug(3,
"offset=%" PRId64
", length=%" PRId64
", offset_offset=%" PRId64
", length_offset=%" PRId64
"\n", offset, length, offset_offset, length_offset);
853 for (i = offset_offset; i < flength; i +=
sizeof(fbuf)) {
856 if ((bytes_read = fread(fbuf, 1,
sizeof(fbuf), ff)) <
sizeof(fbuf) && !feof(ff)) {
857 ast_log(LOG_ERROR,
"Short read?!!\n");
861 for (pos = fbuf; pos < fbuf + bytes_read; pos++) {
862 LINE_COUNTER(pos, format, current_length);
864 if (current_length == length) {
865 length_offset = i + (pos - fbuf) + 1;
869 ast_debug(3,
"length_offset=%" PRId64
", length_offset - i=%" PRId64
"\n", length_offset, length_offset - i);
870 ast_str_append_substr(buf, len, fbuf, (length_offset >= 0) ? length_offset - i : (flength > i +
sizeof(fbuf)) ?
sizeof(fbuf) : flength - i);
872 if (length_offset >= 0) {
882 const char *format2term(
enum file_format f) __attribute__((
const));
883 const char *format2term(
enum file_format f)
885 const char *term[] = {
"",
"\n",
"\r\n",
"\r" };
889 static int file_write(
struct ast_channel *chan,
const char *cmd,
char *data,
const char *value)
898 int64_t offset = 0, length = LLONG_MAX;
899 off_t flength, vlength;
906 sscanf(args.offset,
"%" SCNd64, &offset);
909 sscanf(args.length,
"%" SCNd64, &length);
912 vlength = strlen(value);
914 if (args.argc < 4 || !strchr(args.options,
'l')) {
917 if (args.argc > 3 && strchr(args.options,
'a')) {
919 if (!(ff = fopen(args.filename,
"a"))) {
920 ast_log(LOG_WARNING,
"Cannot open file '%s' for appending: %s\n", args.filename, strerror(errno));
923 if (fwrite(value, 1, vlength, ff) < vlength) {
924 ast_log(LOG_ERROR,
"Short write?!!\n");
928 }
else if (offset == 0 && length == LLONG_MAX) {
929 if (!(ff = fopen(args.filename,
"w"))) {
930 ast_log(LOG_WARNING,
"Cannot open file '%s' for writing: %s\n", args.filename, strerror(errno));
933 if (fwrite(value, 1, vlength, ff) < vlength) {
934 ast_log(LOG_ERROR,
"Short write?!!\n");
940 if (!(ff = fopen(args.filename,
"r+"))) {
941 ast_log(LOG_WARNING,
"Cannot open file '%s' for modification: %s\n", args.filename, strerror(errno));
944 fseeko(ff, 0, SEEK_END);
945 flength = ftello(ff);
948 if (fseeko(ff, offset, SEEK_END)) {
949 ast_log(LOG_ERROR,
"Cannot seek to offset of '%s': %s\n", args.filename, strerror(errno));
953 if ((offset = ftello(ff)) < 0) {
954 ast_log(AST_LOG_ERROR,
"Cannot determine offset position of '%s': %s\n", args.filename, strerror(errno));
961 length = flength - offset + length;
963 ast_log(LOG_ERROR,
"Length '%s' exceeds the file length. No data will be written.\n", args.length);
969 fseeko(ff, offset, SEEK_SET);
971 ast_debug(3,
"offset=%s/%" PRId64
", length=%s/%" PRId64
", vlength=%" PRId64
", flength=%" PRId64
"\n",
972 S_OR(args.offset,
"(null)"), offset,
S_OR(args.length,
"(null)"), length, vlength, flength);
974 if (length == vlength) {
976 if (fwrite(value, 1, vlength, ff) < vlength) {
977 ast_log(LOG_ERROR,
"Short write?!!\n");
980 }
else if (length == LLONG_MAX) {
982 if (fwrite(value, 1, vlength, ff) < vlength) {
983 ast_log(LOG_ERROR,
"Short write?!!\n");
986 if (truncate(args.filename, offset + vlength)) {
987 ast_log(LOG_ERROR,
"Unable to truncate the file: %s\n", strerror(errno));
989 }
else if (length > vlength) {
993 if (fwrite(value, 1, vlength, ff) < vlength) {
994 ast_log(LOG_ERROR,
"Short write?!!\n");
996 fseeko(ff, length - vlength, SEEK_CUR);
997 while ((cur = ftello(ff)) < flength) {
998 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
999 ast_log(LOG_ERROR,
"Short read?!!\n");
1001 fseeko(ff, cur + vlength - length, SEEK_SET);
1002 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1003 ast_log(LOG_ERROR,
"Short write?!!\n");
1006 if (fseeko(ff, cur +
sizeof(fbuf), SEEK_SET) < 0) {
1012 if (truncate(args.filename, flength - (length - vlength))) {
1013 ast_log(LOG_ERROR,
"Unable to truncate the file: %s\n", strerror(errno));
1018 off_t lastwritten = flength + vlength - length;
1021 fseeko(ff, flength -
sizeof(fbuf), SEEK_SET);
1022 while (offset < ftello(ff)) {
1023 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1024 ast_log(LOG_ERROR,
"Short read?!!\n");
1031 fseeko(ff, vlength - length -
sizeof(fbuf), SEEK_CUR);
1034 lastwritten = ftello(ff);
1036 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1037 ast_log(LOG_ERROR,
"Short write?!!\n");
1042 if (lastwritten < offset +
sizeof(fbuf)) {
1051 fseeko(ff, 2 *
sizeof(fbuf) + vlength - length, SEEK_CUR);
1055 if (fseeko(ff, offset + length, SEEK_SET)) {
1056 ast_log(LOG_WARNING,
"Unable to seek to %" PRId64
" + %" PRId64
" != %" PRId64
"?)\n", offset, length, ftello(ff));
1060 ast_debug(1,
"Reading at %" PRId64
"\n", ftello(ff));
1061 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1062 ast_log(LOG_ERROR,
"Short read?!!\n");
1064 fseek(ff, offset, SEEK_SET);
1066 if (fwrite(value, 1, vlength, ff) < vlength) {
1067 ast_log(LOG_ERROR,
"Short write?!!\n");
1069 off_t curpos = ftello(ff);
1070 foplen = lastwritten - curpos;
1071 if (fwrite(fbuf, 1, foplen, ff) < foplen) {
1072 ast_log(LOG_ERROR,
"Short write?!!\n");
1078 enum file_format newline_format = FF_UNKNOWN;
1081 if (args.argc == 5) {
1082 if (tolower(args.format[0]) ==
'u') {
1083 newline_format = FF_UNIX;
1084 }
else if (tolower(args.format[0]) ==
'm') {
1085 newline_format = FF_MAC;
1086 }
else if (tolower(args.format[0]) ==
'd') {
1087 newline_format = FF_DOS;
1090 if (newline_format == FF_UNKNOWN && (newline_format = file2format(args.filename)) == FF_UNKNOWN) {
1091 ast_log(LOG_ERROR,
"File '%s' not in line format\n", args.filename);
1095 if (strchr(args.options,
'a')) {
1097 if (!(ff = fopen(args.filename,
"a"))) {
1098 ast_log(LOG_ERROR,
"Unable to open '%s' for appending: %s\n", args.filename, strerror(errno));
1101 if (fwrite(value, 1, vlength, ff) < vlength) {
1102 ast_log(LOG_ERROR,
"Short write?!!\n");
1103 }
else if (!strchr(args.options,
'd') && fwrite(format2term(newline_format), 1, strlen(format2term(newline_format)), ff) < strlen(format2term(newline_format))) {
1104 ast_log(LOG_ERROR,
"Short write?!!\n");
1107 }
else if (offset == 0 && length == LLONG_MAX) {
1110 if (!(ff = fopen(args.filename,
"w"))) {
1111 ast_log(LOG_ERROR,
"Unable to open '%s' for writing: %s\n", args.filename, strerror(errno));
1114 if (fwrite(value, 1, vlength, ff) < vlength) {
1115 ast_log(LOG_ERROR,
"Short write?!!\n");
1116 }
else if (!strchr(args.options,
'd') && fwrite(format2term(newline_format), 1, strlen(format2term(newline_format)), ff) < strlen(format2term(newline_format))) {
1117 ast_log(LOG_ERROR,
"Short write?!!\n");
1119 if ((truncsize = ftello(ff)) < 0) {
1120 ast_log(AST_LOG_ERROR,
"Unable to determine truncate position of '%s': %s\n", args.filename, strerror(errno));
1123 if (truncsize >= 0 && truncate(args.filename, truncsize)) {
1124 ast_log(LOG_ERROR,
"Unable to truncate file '%s': %s\n", args.filename, strerror(errno));
1128 int64_t offset_offset = (offset == 0 ? 0 : -1), length_offset = -1, flength, i, current_length = 0;
1129 char dos_state = 0, fbuf[4096];
1131 if (offset < 0 && length < offset) {
1133 ast_log(LOG_ERROR,
"Length cannot specify a position prior to the offset\n");
1137 if (!(ff = fopen(args.filename,
"r+"))) {
1138 ast_log(LOG_ERROR,
"Cannot open '%s' for modification: %s\n", args.filename, strerror(errno));
1142 if (fseek(ff, 0, SEEK_END)) {
1143 ast_log(LOG_ERROR,
"Cannot seek to end of file '%s': %s\n", args.filename, strerror(errno));
1147 if ((flength = ftello(ff)) < 0) {
1148 ast_log(AST_LOG_ERROR,
"Cannot determine end position of file '%s': %s\n", args.filename, strerror(errno));
1154 if (offset < 0 || length < 0) {
1156 for (i = (flength /
sizeof(fbuf)) *
sizeof(fbuf); i >= 0; i -=
sizeof(fbuf)) {
1158 if (fseeko(ff, i, SEEK_SET)) {
1159 ast_log(LOG_ERROR,
"Cannot seek to offset %" PRId64
": %s\n", i, strerror(errno));
1161 if (i +
sizeof(fbuf) >= flength) {
1162 memset(fbuf, 0,
sizeof(fbuf));
1164 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1165 ast_log(LOG_ERROR,
"Short read: %s\n", strerror(errno));
1169 for (pos = fbuf +
sizeof(fbuf) - 1; pos >= fbuf; pos--) {
1170 LINE_COUNTER(pos, newline_format, count);
1172 if (length < 0 && count * -1 == length) {
1173 length_offset = i + (pos - fbuf);
1174 }
else if (offset < 0 && count * -1 == (offset - 1)) {
1176 if (newline_format == FF_DOS) {
1177 offset_offset = i + (pos - fbuf) + 2;
1179 offset_offset = i + (pos - fbuf) + 1;
1184 if ((offset < 0 && offset_offset >= 0) || (offset >= 0 && length_offset >= 0)) {
1189 if (offset < 0 && offset_offset < 0 && offset == count * -1) {
1197 fseek(ff, 0, SEEK_SET);
1198 for (i = 0; i < flength; i +=
sizeof(fbuf)) {
1200 if (i +
sizeof(fbuf) >= flength) {
1201 memset(fbuf, 0,
sizeof(fbuf));
1203 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1204 ast_log(LOG_ERROR,
"Short read?!!\n");
1208 for (pos = fbuf; pos < fbuf +
sizeof(fbuf); pos++) {
1209 LINE_COUNTER(pos, newline_format, count);
1211 if (count == offset) {
1212 offset_offset = i + (pos - fbuf) + 1;
1216 if (offset_offset >= 0) {
1222 if (offset_offset < 0) {
1223 ast_log(LOG_ERROR,
"Offset '%s' refers to before the beginning of the file!\n", args.offset);
1229 length_offset = offset_offset;
1230 }
else if (length == LLONG_MAX) {
1231 length_offset = flength;
1235 if (length_offset < 0) {
1236 fseeko(ff, offset_offset, SEEK_SET);
1237 for (i = offset_offset; i < flength; i +=
sizeof(fbuf)) {
1239 if (i +
sizeof(fbuf) >= flength) {
1240 memset(fbuf, 0,
sizeof(fbuf));
1242 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1243 ast_log(LOG_ERROR,
"Short read?!!\n");
1247 for (pos = fbuf; pos < fbuf +
sizeof(fbuf); pos++) {
1248 LINE_COUNTER(pos, newline_format, current_length);
1250 if (current_length == length) {
1251 length_offset = i + (pos - fbuf) + 1;
1255 if (length_offset >= 0) {
1259 if (length_offset < 0) {
1261 ast_debug(3,
"Exceeds length of file? length=%" PRId64
", count=%" PRId64
", flength=%" PRId64
"\n", length, current_length, flength);
1262 length_offset = flength;
1267 if (length_offset - offset_offset == vlength + (strchr(args.options,
'd') ? 0 : strlen(format2term(newline_format)))) {
1269 fseeko(ff, offset_offset, SEEK_SET);
1270 if (fwrite(value, 1, vlength, ff) < vlength) {
1271 ast_log(LOG_ERROR,
"Short write?!!\n");
1272 }
else if (!strchr(args.options,
'd') && fwrite(format2term(newline_format), 1, strlen(format2term(newline_format)), ff) < strlen(format2term(newline_format))) {
1273 ast_log(LOG_ERROR,
"Short write?!!\n");
1276 }
else if (length_offset - offset_offset > vlength + (strchr(args.options,
'd') ? 0 : strlen(format2term(newline_format)))) {
1279 int64_t length_length = length_offset - offset_offset;
1280 size_t vlen = vlength + (strchr(args.options,
'd') ? 0 : strlen(format2term(newline_format)));
1282 ast_debug(3,
"offset=%s/%" PRId64
", length=%s/%" PRId64
" (%" PRId64
"), vlength=%" PRId64
", flength=%" PRId64
"\n",
1283 args.offset, offset_offset, args.length, length_offset, length_length, vlength, flength);
1285 fseeko(ff, offset_offset, SEEK_SET);
1286 if (fwrite(value, 1, vlength, ff) < vlength) {
1287 ast_log(LOG_ERROR,
"Short write?!!\n");
1290 }
else if (!strchr(args.options,
'd') && fwrite(format2term(newline_format), 1, vlen - vlength, ff) < vlen - vlength) {
1291 ast_log(LOG_ERROR,
"Short write?!!\n");
1295 while ((cur = ftello(ff)) < flength) {
1297 ast_log(AST_LOG_ERROR,
"Unable to determine last write position for '%s': %s\n", args.filename, strerror(errno));
1301 fseeko(ff, length_length - vlen, SEEK_CUR);
1302 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1303 ast_log(LOG_ERROR,
"Short read?!!\n");
1308 fseeko(ff, cur, SEEK_SET);
1309 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1310 ast_log(LOG_ERROR,
"Short write?!!\n");
1316 if (truncate(args.filename, flength - (length_length - vlen))) {
1317 ast_log(LOG_ERROR,
"Truncation of file failed: %s\n", strerror(errno));
1321 size_t vlen = vlength + (strchr(args.options,
'd') ? 0 : strlen(format2term(newline_format)));
1322 int64_t origlen = length_offset - offset_offset;
1323 off_t lastwritten = flength + vlen - origlen;
1325 ast_debug(3,
"offset=%s/%" PRId64
", length=%s/%" PRId64
", vlength=%" PRId64
", flength=%" PRId64
"\n",
1326 args.offset, offset_offset, args.length, length_offset, vlength, flength);
1328 fseeko(ff, flength -
sizeof(fbuf), SEEK_SET);
1329 while (offset_offset +
sizeof(fbuf) < ftello(ff)) {
1330 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1331 ast_log(LOG_ERROR,
"Short read?!!\n");
1335 fseeko(ff,
sizeof(fbuf) - vlen - origlen, SEEK_CUR);
1336 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1337 ast_log(LOG_ERROR,
"Short write?!!\n");
1341 if ((lastwritten = ftello(ff) -
sizeof(fbuf)) < offset_offset +
sizeof(fbuf)) {
1344 fseeko(ff, 2 *
sizeof(fbuf) + vlen - origlen, SEEK_CUR);
1346 fseek(ff, length_offset, SEEK_SET);
1347 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1348 ast_log(LOG_ERROR,
"Short read?!!\n");
1352 fseek(ff, offset_offset, SEEK_SET);
1353 if (fwrite(value, 1, vlength, ff) < vlength) {
1354 ast_log(LOG_ERROR,
"Short write?!!\n");
1357 }
else if (!strchr(args.options,
'd') && fwrite(format2term(newline_format), 1, strlen(format2term(newline_format)), ff) < strlen(format2term(newline_format))) {
1358 ast_log(LOG_ERROR,
"Short write?!!\n");
1362 off_t curpos = ftello(ff);
1363 foplen = lastwritten - curpos;
1364 if (fwrite(fbuf, 1, foplen, ff) < foplen) {
1365 ast_log(LOG_ERROR,
"Short write?!!\n");
1391 .write = file_write,
1395 .
name =
"FILE_COUNT_LINE",
1396 .read2 = file_count_line,
1401 .
name =
"FILE_FORMAT",
1402 .read2 = file_format,
1408 .read = file_dirname,
1414 .read = file_basename,
1418 static int unload_module(
void)
1433 static int load_module(
void)
1448 AST_MODULE_INFO_STANDARD(
ASTERISK_GPL_KEY,
"Environment/filesystem dialplan functions");
Main Channel structure associated with a channel.
Asterisk main include file. File version handling, generic pbx functions.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
#define ast_custom_function_register_escalating(acf, escalation)
Register a custom function which requires escalated privileges.
General Asterisk PBX channel definitions.
char * ast_str_append_substr(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Append a non-NULL terminated substring to the end of a dynamic string.
Data structure associated with a custom dialplan function.
#define ast_debug(level,...)
Log a DEBUG message.
Core PBX routines and definitions.
Support for dynamic strings.
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define ast_custom_function_register(acf)
Register a custom function.
#define AST_APP_ARG(name)
Define an application argument.