649 int64_t offset_offset = -1, length_offset = -1;
662 sscanf(
args.offset,
"%" SCNd64, &offset);
665 sscanf(
args.length,
"%" SCNd64, &length);
668 if (
args.argc < 4 || !strchr(
args.options,
'l')) {
672 if (!(ff = fopen(
args.filename,
"r"))) {
677 if (fseeko(ff, 0, SEEK_END) < 0) {
682 flength = ftello(ff);
685 fseeko(ff, offset, SEEK_END);
686 if ((offset = ftello(ff)) < 0) {
693 fseeko(ff, length, SEEK_END);
694 if ((length = ftello(ff)) - offset < 0) {
700 fseeko(ff, 0, SEEK_END);
706 fseeko(ff, offset, SEEK_SET);
707 for (off_i = ftello(ff); off_i < flength && off_i < offset + length; off_i +=
sizeof(fbuf)) {
709 size_t toappend =
sizeof(fbuf);
711 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
717 if (off_i + toappend > offset + length) {
718 toappend =
MIN(offset + length - off_i, flength - off_i);
728 if (
args.argc == 5) {
729 if (tolower(
args.fileformat[0]) ==
'd') {
731 }
else if (tolower(
args.fileformat[0]) ==
'm') {
733 }
else if (tolower(
args.fileformat[0]) ==
'u') {
745 if (offset < 0 && length <= offset) {
748 }
else if (offset == 0) {
752 if (!(ff = fopen(
args.filename,
"r"))) {
757 if (fseek(ff, 0, SEEK_END)) {
763 flength = ftello(ff);
766 length_offset = flength;
770 if (offset < 0 || length < 0) {
774 for (i = (flength /
sizeof(fbuf)) *
sizeof(fbuf); i >= 0; i -=
sizeof(fbuf)) {
777 if (fseeko(ff, i, SEEK_SET)) {
780 end = fread(fbuf, 1,
sizeof(fbuf), ff);
781 for (pos = (
end <
sizeof(fbuf) ? fbuf +
end - 1 : fbuf +
sizeof(fbuf) - 1); pos >= fbuf; pos--) {
784 if (length < 0 && count * -1 == length) {
785 length_offset = i + (pos - fbuf);
786 }
else if (offset < 0 && count * -1 == (offset - 1)) {
789 offset_offset = i + (pos - fbuf) + 2;
791 offset_offset = i + (pos - fbuf) + 1;
796 if ((offset < 0 && offset_offset >= 0) || (offset >= 0 && length_offset >= 0)) {
801 if (offset < 0 && offset_offset < 0 && offset == count * -1) {
809 fseek(ff, 0, SEEK_SET);
810 for (i = 0; i < flength; i +=
sizeof(fbuf)) {
812 if (i +
sizeof(fbuf) <= flength) {
814 memset(fbuf, 0,
sizeof(fbuf));
816 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
821 for (pos = fbuf; pos < fbuf +
sizeof(fbuf); pos++) {
824 if (count == offset) {
825 offset_offset = i + (pos - fbuf) + 1;
829 if (offset_offset >= 0) {
835 if (offset_offset < 0) {
842 if (fseeko(ff, offset_offset, SEEK_SET)) {
850 if (length_offset >= 0) {
851 ast_debug(3,
"offset=%" PRId64
", length=%" PRId64
", offset_offset=%" PRId64
", length_offset=%" PRId64
"\n", offset, length, offset_offset, length_offset);
852 for (i = offset_offset; i < length_offset; i +=
sizeof(fbuf)) {
853 if (fread(fbuf, 1, i +
sizeof(fbuf) > flength ? flength - i :
sizeof(fbuf), ff) < (i +
sizeof(fbuf) > flength ? flength - i :
sizeof(fbuf))) {
856 ast_debug(3,
"Appending first %" PRId64
" bytes of fbuf=%s\n", (int64_t)(i +
sizeof(fbuf) > length_offset ? length_offset - i :
sizeof(fbuf)), fbuf);
859 }
else if (length == 0) {
863 int64_t current_length = 0;
865 ast_debug(3,
"offset=%" PRId64
", length=%" PRId64
", offset_offset=%" PRId64
", length_offset=%" PRId64
"\n", offset, length, offset_offset, length_offset);
866 for (i = offset_offset; i < flength; i +=
sizeof(fbuf)) {
869 if ((bytes_read = fread(fbuf, 1,
sizeof(fbuf), ff)) <
sizeof(fbuf) && !feof(ff)) {
874 for (pos = fbuf; pos < fbuf + bytes_read; pos++) {
877 if (current_length == length) {
878 length_offset = i + (pos - fbuf) + 1;
882 ast_debug(3,
"length_offset=%" PRId64
", length_offset - i=%" PRId64
"\n", length_offset, length_offset - i);
883 ast_str_append_substr(
buf,
len, fbuf, (length_offset >= 0) ? length_offset - i : (flength > i +
sizeof(fbuf)) ?
sizeof(fbuf) : flength - i);
885 if (length_offset >= 0) {
912 off_t flength, vlength;
919 sscanf(
args.offset,
"%" SCNd64, &offset);
922 sscanf(
args.length,
"%" SCNd64, &length);
925 vlength = strlen(
value);
927 if (
args.argc < 4 || !strchr(
args.options,
'l')) {
930 if (
args.argc > 3 && strchr(
args.options,
'a')) {
932 if (!(ff = fopen(
args.filename,
"a"))) {
936 if (fwrite(
value, 1, vlength, ff) < vlength) {
941 }
else if (offset == 0 && length ==
LLONG_MAX) {
942 if (!(ff = fopen(
args.filename,
"w"))) {
946 if (fwrite(
value, 1, vlength, ff) < vlength) {
953 if (!(ff = fopen(
args.filename,
"r+"))) {
957 fseeko(ff, 0, SEEK_END);
958 flength = ftello(ff);
961 if (fseeko(ff, offset, SEEK_END)) {
966 if ((offset = ftello(ff)) < 0) {
974 length = flength - offset + length;
976 ast_log(
LOG_ERROR,
"Length '%s' exceeds the file length. No data will be written.\n",
args.length);
982 fseeko(ff, offset, SEEK_SET);
984 ast_debug(3,
"offset=%s/%" PRId64
", length=%s/%" PRId64
", vlength=%" PRId64
", flength=%" PRId64
"\n",
985 S_OR(
args.offset,
"(null)"), offset,
S_OR(
args.length,
"(null)"), length, vlength, flength);
987 if (length == vlength) {
989 if (fwrite(
value, 1, vlength, ff) < vlength) {
995 if (fwrite(
value, 1, vlength, ff) < vlength) {
999 if (truncate(
args.filename, offset + vlength)) {
1002 }
else if (length > vlength) {
1006 if (fwrite(
value, 1, vlength, ff) < vlength) {
1009 fseeko(ff, length - vlength, SEEK_CUR);
1010 while ((cur = ftello(ff)) < flength) {
1011 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1014 fseeko(ff, cur + vlength - length, SEEK_SET);
1015 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1019 if (fseeko(ff, cur +
sizeof(fbuf), SEEK_SET) < 0) {
1025 if (truncate(
args.filename, flength - (length - vlength))) {
1031 off_t lastwritten = flength + vlength - length;
1034 fseeko(ff, flength -
sizeof(fbuf), SEEK_SET);
1035 while (offset < ftello(ff)) {
1036 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1044 fseeko(ff, vlength - length -
sizeof(fbuf), SEEK_CUR);
1047 lastwritten = ftello(ff);
1049 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1055 if (lastwritten < offset +
sizeof(fbuf)) {
1064 fseeko(ff, 2 *
sizeof(fbuf) + vlength - length, SEEK_CUR);
1068 if (fseeko(ff, offset + length, SEEK_SET)) {
1069 ast_log(
LOG_WARNING,
"Unable to seek to %" PRId64
" + %" PRId64
" != %" PRId64
"?)\n", offset, length, ftello(ff));
1073 ast_debug(1,
"Reading at %" PRId64
"\n", ftello(ff));
1074 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1077 fseek(ff, offset, SEEK_SET);
1079 if (fwrite(
value, 1, vlength, ff) < vlength) {
1082 off_t curpos = ftello(ff);
1083 foplen = lastwritten - curpos;
1084 if (fwrite(fbuf, 1, foplen, ff) < foplen) {
1094 if (
args.argc == 5) {
1095 if (tolower(
args.format[0]) ==
'u') {
1097 }
else if (tolower(
args.format[0]) ==
'm') {
1099 }
else if (tolower(
args.format[0]) ==
'd') {
1108 if (strchr(
args.options,
'a')) {
1110 if (!(ff = fopen(
args.filename,
"a"))) {
1114 if (fwrite(
value, 1, vlength, ff) < vlength) {
1120 }
else if (offset == 0 && length ==
LLONG_MAX) {
1123 if (!(ff = fopen(
args.filename,
"w"))) {
1127 if (fwrite(
value, 1, vlength, ff) < vlength) {
1132 if ((truncsize = ftello(ff)) < 0) {
1136 if (truncsize >= 0 && truncate(
args.filename, truncsize)) {
1141 int64_t offset_offset = (offset == 0 ? 0 : -1), length_offset = -1, flength, i, current_length = 0;
1142 char dos_state = 0, fbuf[4096];
1144 if (offset < 0 && length < offset) {
1146 ast_log(
LOG_ERROR,
"Length cannot specify a position prior to the offset\n");
1150 if (!(ff = fopen(
args.filename,
"r+"))) {
1155 if (fseek(ff, 0, SEEK_END)) {
1160 if ((flength = ftello(ff)) < 0) {
1167 if (offset < 0 || length < 0) {
1169 for (i = (flength /
sizeof(fbuf)) *
sizeof(fbuf); i >= 0; i -=
sizeof(fbuf)) {
1171 if (fseeko(ff, i, SEEK_SET)) {
1174 if (i +
sizeof(fbuf) >= flength) {
1175 memset(fbuf, 0,
sizeof(fbuf));
1177 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1182 for (pos = fbuf +
sizeof(fbuf) - 1; pos >= fbuf; pos--) {
1185 if (length < 0 && count * -1 == length) {
1186 length_offset = i + (pos - fbuf);
1187 }
else if (offset < 0 && count * -1 == (offset - 1)) {
1189 if (newline_format ==
FF_DOS) {
1190 offset_offset = i + (pos - fbuf) + 2;
1192 offset_offset = i + (pos - fbuf) + 1;
1197 if ((offset < 0 && offset_offset >= 0) || (offset >= 0 && length_offset >= 0)) {
1202 if (offset < 0 && offset_offset < 0 && offset == count * -1) {
1210 fseek(ff, 0, SEEK_SET);
1211 for (i = 0; i < flength; i +=
sizeof(fbuf)) {
1213 if (i +
sizeof(fbuf) >= flength) {
1214 memset(fbuf, 0,
sizeof(fbuf));
1216 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1221 for (pos = fbuf; pos < fbuf +
sizeof(fbuf); pos++) {
1224 if (count == offset) {
1225 offset_offset = i + (pos - fbuf) + 1;
1229 if (offset_offset >= 0) {
1235 if (offset_offset < 0) {
1242 length_offset = offset_offset;
1244 length_offset = flength;
1248 if (length_offset < 0) {
1249 fseeko(ff, offset_offset, SEEK_SET);
1250 for (i = offset_offset; i < flength; i +=
sizeof(fbuf)) {
1252 if (i +
sizeof(fbuf) >= flength) {
1253 memset(fbuf, 0,
sizeof(fbuf));
1255 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1260 for (pos = fbuf; pos < fbuf +
sizeof(fbuf); pos++) {
1263 if (current_length == length) {
1264 length_offset = i + (pos - fbuf) + 1;
1268 if (length_offset >= 0) {
1272 if (length_offset < 0) {
1274 ast_debug(3,
"Exceeds length of file? length=%" PRId64
", count=%" PRId64
", flength=%" PRId64
"\n", length, current_length, flength);
1275 length_offset = flength;
1280 if (length_offset - offset_offset == vlength + (strchr(
args.options,
'd') ? 0 : strlen(
format2term(newline_format)))) {
1282 fseeko(ff, offset_offset, SEEK_SET);
1283 if (fwrite(
value, 1, vlength, ff) < vlength) {
1289 }
else if (length_offset - offset_offset > vlength + (strchr(
args.options,
'd') ? 0 : strlen(
format2term(newline_format)))) {
1292 int64_t length_length = length_offset - offset_offset;
1293 size_t vlen = vlength + (strchr(
args.options,
'd') ? 0 : strlen(
format2term(newline_format)));
1295 ast_debug(3,
"offset=%s/%" PRId64
", length=%s/%" PRId64
" (%" PRId64
"), vlength=%" PRId64
", flength=%" PRId64
"\n",
1296 args.offset, offset_offset,
args.length, length_offset, length_length, vlength, flength);
1298 fseeko(ff, offset_offset, SEEK_SET);
1299 if (fwrite(
value, 1, vlength, ff) < vlength) {
1303 }
else if (!strchr(
args.options,
'd') && fwrite(
format2term(newline_format), 1, vlen - vlength, ff) < vlen - vlength) {
1308 while ((cur = ftello(ff)) < flength) {
1314 fseeko(ff, length_length - vlen, SEEK_CUR);
1315 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1321 fseeko(ff, cur, SEEK_SET);
1322 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1329 if (truncate(
args.filename, flength - (length_length - vlen))) {
1334 size_t vlen = vlength + (strchr(
args.options,
'd') ? 0 : strlen(
format2term(newline_format)));
1335 int64_t origlen = length_offset - offset_offset;
1336 off_t lastwritten = flength + vlen - origlen;
1338 ast_debug(3,
"offset=%s/%" PRId64
", length=%s/%" PRId64
", vlength=%" PRId64
", flength=%" PRId64
"\n",
1339 args.offset, offset_offset,
args.length, length_offset, vlength, flength);
1341 fseeko(ff, flength -
sizeof(fbuf), SEEK_SET);
1342 while (offset_offset +
sizeof(fbuf) < ftello(ff)) {
1343 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1348 fseeko(ff,
sizeof(fbuf) - vlen - origlen, SEEK_CUR);
1349 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1354 if ((lastwritten = ftello(ff) -
sizeof(fbuf)) < offset_offset +
sizeof(fbuf)) {
1357 fseeko(ff, 2 *
sizeof(fbuf) + vlen - origlen, SEEK_CUR);
1359 fseek(ff, length_offset, SEEK_SET);
1360 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1365 fseek(ff, offset_offset, SEEK_SET);
1366 if (fwrite(
value, 1, vlength, ff) < vlength) {
1375 off_t curpos = ftello(ff);
1376 foplen = lastwritten - curpos;
1377 if (fwrite(fbuf, 1, foplen, ff) < foplen) {