756 off_t flength, vlength;
763 sscanf(
args.offset,
"%" SCNd64, &offset);
766 sscanf(
args.length,
"%" SCNd64, &length);
769 vlength = strlen(
value);
771 if (
args.argc < 4 || !strchr(
args.options,
'l')) {
774 if (
args.argc > 3 && strchr(
args.options,
'a')) {
776 if (!(ff = fopen(
args.filename,
"a"))) {
780 if (fwrite(
value, 1, vlength, ff) < vlength) {
785 }
else if (offset == 0 && length ==
LLONG_MAX) {
786 if (!(ff = fopen(
args.filename,
"w"))) {
790 if (fwrite(
value, 1, vlength, ff) < vlength) {
797 if (!(ff = fopen(
args.filename,
"r+"))) {
801 fseeko(ff, 0, SEEK_END);
802 flength = ftello(ff);
805 if (fseeko(ff, offset, SEEK_END)) {
810 if ((offset = ftello(ff)) < 0) {
818 length = flength - offset + length;
820 ast_log(
LOG_ERROR,
"Length '%s' exceeds the file length. No data will be written.\n",
args.length);
826 fseeko(ff, offset, SEEK_SET);
828 ast_debug(3,
"offset=%s/%" PRId64
", length=%s/%" PRId64
", vlength=%" PRId64
", flength=%" PRId64
"\n",
829 S_OR(
args.offset,
"(null)"), offset,
S_OR(
args.length,
"(null)"), length, vlength, flength);
831 if (length == vlength) {
833 if (fwrite(
value, 1, vlength, ff) < vlength) {
839 if (fwrite(
value, 1, vlength, ff) < vlength) {
843 if (truncate(
args.filename, offset + vlength)) {
846 }
else if (length > vlength) {
850 if (fwrite(
value, 1, vlength, ff) < vlength) {
853 fseeko(ff, length - vlength, SEEK_CUR);
854 while ((cur = ftello(ff)) < flength) {
855 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
858 fseeko(ff, cur + vlength - length, SEEK_SET);
859 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
863 if (fseeko(ff, cur +
sizeof(fbuf), SEEK_SET) < 0) {
869 if (truncate(
args.filename, flength - (length - vlength))) {
875 off_t lastwritten = flength + vlength - length;
878 fseeko(ff, flength -
sizeof(fbuf), SEEK_SET);
879 while (offset < ftello(ff)) {
880 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
888 fseeko(ff, vlength - length -
sizeof(fbuf), SEEK_CUR);
891 lastwritten = ftello(ff);
893 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
899 if (lastwritten < offset +
sizeof(fbuf)) {
908 fseeko(ff, 2 *
sizeof(fbuf) + vlength - length, SEEK_CUR);
912 if (fseeko(ff, offset + length, SEEK_SET)) {
913 ast_log(
LOG_WARNING,
"Unable to seek to %" PRId64
" + %" PRId64
" != %" PRId64
"?)\n", offset, length, ftello(ff));
917 ast_debug(1,
"Reading at %" PRId64
"\n", ftello(ff));
918 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
921 fseek(ff, offset, SEEK_SET);
923 if (fwrite(
value, 1, vlength, ff) < vlength) {
926 off_t curpos = ftello(ff);
927 foplen = lastwritten - curpos;
928 if (fwrite(fbuf, 1, foplen, ff) < foplen) {
938 if (
args.argc == 5) {
939 if (tolower(
args.format[0]) ==
'u') {
941 }
else if (tolower(
args.format[0]) ==
'm') {
943 }
else if (tolower(
args.format[0]) ==
'd') {
952 if (strchr(
args.options,
'a')) {
954 if (!(ff = fopen(
args.filename,
"a"))) {
958 if (fwrite(
value, 1, vlength, ff) < vlength) {
964 }
else if (offset == 0 && length ==
LLONG_MAX) {
967 if (!(ff = fopen(
args.filename,
"w"))) {
971 if (fwrite(
value, 1, vlength, ff) < vlength) {
976 if ((truncsize = ftello(ff)) < 0) {
980 if (truncsize >= 0 && truncate(
args.filename, truncsize)) {
985 int64_t offset_offset = (offset == 0 ? 0 : -1), length_offset = -1, flength, i, current_length = 0;
986 char dos_state = 0, fbuf[4096];
988 if (offset < 0 && length < offset) {
990 ast_log(
LOG_ERROR,
"Length cannot specify a position prior to the offset\n");
994 if (!(ff = fopen(
args.filename,
"r+"))) {
999 if (fseek(ff, 0, SEEK_END)) {
1004 if ((flength = ftello(ff)) < 0) {
1011 if (offset < 0 || length < 0) {
1013 for (i = (flength /
sizeof(fbuf)) *
sizeof(fbuf); i >= 0; i -=
sizeof(fbuf)) {
1015 if (fseeko(ff, i, SEEK_SET)) {
1018 if (i +
sizeof(fbuf) >= flength) {
1019 memset(fbuf, 0,
sizeof(fbuf));
1021 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1026 for (pos = fbuf +
sizeof(fbuf) - 1; pos >= fbuf; pos--) {
1029 if (length < 0 && count * -1 == length) {
1030 length_offset = i + (pos - fbuf);
1031 }
else if (offset < 0 && count * -1 == (offset - 1)) {
1033 if (newline_format ==
FF_DOS) {
1034 offset_offset = i + (pos - fbuf) + 2;
1036 offset_offset = i + (pos - fbuf) + 1;
1041 if ((offset < 0 && offset_offset >= 0) || (offset >= 0 && length_offset >= 0)) {
1046 if (offset < 0 && offset_offset < 0 && offset == count * -1) {
1054 fseek(ff, 0, SEEK_SET);
1055 for (i = 0; i < flength; i +=
sizeof(fbuf)) {
1057 if (i +
sizeof(fbuf) >= flength) {
1058 memset(fbuf, 0,
sizeof(fbuf));
1060 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1065 for (pos = fbuf; pos < fbuf +
sizeof(fbuf); pos++) {
1068 if (count == offset) {
1069 offset_offset = i + (pos - fbuf) + 1;
1073 if (offset_offset >= 0) {
1079 if (offset_offset < 0) {
1086 length_offset = offset_offset;
1088 length_offset = flength;
1092 if (length_offset < 0) {
1093 fseeko(ff, offset_offset, SEEK_SET);
1094 for (i = offset_offset; i < flength; i +=
sizeof(fbuf)) {
1096 if (i +
sizeof(fbuf) >= flength) {
1097 memset(fbuf, 0,
sizeof(fbuf));
1099 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1104 for (pos = fbuf; pos < fbuf +
sizeof(fbuf); pos++) {
1107 if (current_length == length) {
1108 length_offset = i + (pos - fbuf) + 1;
1112 if (length_offset >= 0) {
1116 if (length_offset < 0) {
1118 ast_debug(3,
"Exceeds length of file? length=%" PRId64
", count=%" PRId64
", flength=%" PRId64
"\n", length, current_length, flength);
1119 length_offset = flength;
1124 if (length_offset - offset_offset == vlength + (strchr(
args.options,
'd') ? 0 : strlen(
format2term(newline_format)))) {
1126 fseeko(ff, offset_offset, SEEK_SET);
1127 if (fwrite(
value, 1, vlength, ff) < vlength) {
1133 }
else if (length_offset - offset_offset > vlength + (strchr(
args.options,
'd') ? 0 : strlen(
format2term(newline_format)))) {
1136 int64_t length_length = length_offset - offset_offset;
1137 size_t vlen = vlength + (strchr(
args.options,
'd') ? 0 : strlen(
format2term(newline_format)));
1139 ast_debug(3,
"offset=%s/%" PRId64
", length=%s/%" PRId64
" (%" PRId64
"), vlength=%" PRId64
", flength=%" PRId64
"\n",
1140 args.offset, offset_offset,
args.length, length_offset, length_length, vlength, flength);
1142 fseeko(ff, offset_offset, SEEK_SET);
1143 if (fwrite(
value, 1, vlength, ff) < vlength) {
1147 }
else if (!strchr(
args.options,
'd') && fwrite(
format2term(newline_format), 1, vlen - vlength, ff) < vlen - vlength) {
1152 while ((cur = ftello(ff)) < flength) {
1158 fseeko(ff, length_length - vlen, SEEK_CUR);
1159 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1165 fseeko(ff, cur, SEEK_SET);
1166 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1173 if (truncate(
args.filename, flength - (length_length - vlen))) {
1178 size_t vlen = vlength + (strchr(
args.options,
'd') ? 0 : strlen(
format2term(newline_format)));
1179 int64_t origlen = length_offset - offset_offset;
1180 off_t lastwritten = flength + vlen - origlen;
1182 ast_debug(3,
"offset=%s/%" PRId64
", length=%s/%" PRId64
", vlength=%" PRId64
", flength=%" PRId64
"\n",
1183 args.offset, offset_offset,
args.length, length_offset, vlength, flength);
1185 fseeko(ff, flength -
sizeof(fbuf), SEEK_SET);
1186 while (offset_offset +
sizeof(fbuf) < ftello(ff)) {
1187 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1192 fseeko(ff,
sizeof(fbuf) - vlen - origlen, SEEK_CUR);
1193 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1198 if ((lastwritten = ftello(ff) -
sizeof(fbuf)) < offset_offset +
sizeof(fbuf)) {
1201 fseeko(ff, 2 *
sizeof(fbuf) + vlen - origlen, SEEK_CUR);
1203 fseek(ff, length_offset, SEEK_SET);
1204 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1209 fseek(ff, offset_offset, SEEK_SET);
1210 if (fwrite(
value, 1, vlength, ff) < vlength) {
1219 off_t curpos = ftello(ff);
1220 foplen = lastwritten - curpos;
1221 if (fwrite(fbuf, 1, foplen, ff) < foplen) {
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
const char * format2term(enum file_format f)
static enum file_format file2format(const char *filename)
#define ast_debug(level,...)
Log a DEBUG message.
#define LINE_COUNTER(cptr, term, counter)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
static snd_pcm_format_t format
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_APP_ARG(name)
Define an application argument.