652 int64_t offset_offset = -1, length_offset = -1;
665 sscanf(
args.offset,
"%" SCNd64, &offset);
668 sscanf(
args.length,
"%" SCNd64, &length);
671 if (
args.argc < 4 || !strchr(
args.options,
'l')) {
675 if (!(ff = fopen(
args.filename,
"r"))) {
680 if (fseeko(ff, 0, SEEK_END) < 0) {
685 flength = ftello(ff);
688 fseeko(ff, offset, SEEK_END);
689 if ((offset = ftello(ff)) < 0) {
696 fseeko(ff, length, SEEK_END);
697 if ((length = ftello(ff)) - offset < 0) {
703 fseeko(ff, 0, SEEK_END);
709 fseeko(ff, offset, SEEK_SET);
710 for (off_i = ftello(ff); off_i < flength && off_i < offset + length; off_i +=
sizeof(fbuf)) {
712 size_t toappend =
sizeof(fbuf);
714 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
720 if (off_i + toappend > offset + length) {
721 toappend =
MIN(offset + length - off_i, flength - off_i);
731 if (
args.argc == 5) {
732 if (tolower(
args.fileformat[0]) ==
'd') {
734 }
else if (tolower(
args.fileformat[0]) ==
'm') {
736 }
else if (tolower(
args.fileformat[0]) ==
'u') {
748 if (offset < 0 && length <= offset) {
751 }
else if (offset == 0) {
755 if (!(ff = fopen(
args.filename,
"r"))) {
760 if (fseek(ff, 0, SEEK_END)) {
766 flength = ftello(ff);
769 length_offset = flength;
773 if (offset < 0 || length < 0) {
777 for (i = (flength /
sizeof(fbuf)) *
sizeof(fbuf); i >= 0; i -=
sizeof(fbuf)) {
780 if (fseeko(ff, i, SEEK_SET)) {
783 end = fread(fbuf, 1,
sizeof(fbuf), ff);
784 for (pos = (
end <
sizeof(fbuf) ? fbuf +
end - 1 : fbuf +
sizeof(fbuf) - 1); pos >= fbuf; pos--) {
787 if (length < 0 && count * -1 == length) {
788 length_offset = i + (pos - fbuf);
789 }
else if (offset < 0 && count * -1 == (offset - 1)) {
792 offset_offset = i + (pos - fbuf) + 2;
794 offset_offset = i + (pos - fbuf) + 1;
799 if ((offset < 0 && offset_offset >= 0) || (offset >= 0 && length_offset >= 0)) {
804 if (offset < 0 && offset_offset < 0 && offset == count * -1) {
812 fseek(ff, 0, SEEK_SET);
813 for (i = 0; i < flength; i +=
sizeof(fbuf)) {
815 if (i +
sizeof(fbuf) <= flength) {
817 memset(fbuf, 0,
sizeof(fbuf));
819 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
824 for (pos = fbuf; pos < fbuf +
sizeof(fbuf); pos++) {
827 if (count == offset) {
828 offset_offset = i + (pos - fbuf) + 1;
832 if (offset_offset >= 0) {
838 if (offset_offset < 0) {
845 if (fseeko(ff, offset_offset, SEEK_SET)) {
853 if (length_offset >= 0) {
854 ast_debug(3,
"offset=%" PRId64
", length=%" PRId64
", offset_offset=%" PRId64
", length_offset=%" PRId64
"\n", offset, length, offset_offset, length_offset);
855 for (i = offset_offset; i < length_offset; i +=
sizeof(fbuf)) {
856 if (fread(fbuf, 1, i +
sizeof(fbuf) > flength ? flength - i :
sizeof(fbuf), ff) < (i +
sizeof(fbuf) > flength ? flength - i :
sizeof(fbuf))) {
859 ast_debug(3,
"Appending first %" PRId64
" bytes of fbuf=%s\n", (int64_t)(i +
sizeof(fbuf) > length_offset ? length_offset - i :
sizeof(fbuf)), fbuf);
862 }
else if (length == 0) {
866 int64_t current_length = 0;
868 ast_debug(3,
"offset=%" PRId64
", length=%" PRId64
", offset_offset=%" PRId64
", length_offset=%" PRId64
"\n", offset, length, offset_offset, length_offset);
869 for (i = offset_offset; i < flength; i +=
sizeof(fbuf)) {
872 if ((bytes_read = fread(fbuf, 1,
sizeof(fbuf), ff)) <
sizeof(fbuf) && !feof(ff)) {
877 for (pos = fbuf; pos < fbuf + bytes_read; pos++) {
880 if (current_length == length) {
881 length_offset = i + (pos - fbuf) + 1;
885 ast_debug(3,
"length_offset=%" PRId64
", length_offset - i=%" PRId64
"\n", length_offset, length_offset - i);
886 ast_str_append_substr(
buf,
len, fbuf, (length_offset >= 0) ? length_offset - i : (flength > i +
sizeof(fbuf)) ?
sizeof(fbuf) : flength - i);
888 if (length_offset >= 0) {
915 off_t flength, vlength;
922 sscanf(
args.offset,
"%" SCNd64, &offset);
925 sscanf(
args.length,
"%" SCNd64, &length);
928 vlength = strlen(
value);
930 if (
args.argc < 4 || !strchr(
args.options,
'l')) {
933 if (
args.argc > 3 && strchr(
args.options,
'a')) {
935 if (!(ff = fopen(
args.filename,
"a"))) {
939 if (fwrite(
value, 1, vlength, ff) < vlength) {
944 }
else if (offset == 0 && length ==
LLONG_MAX) {
945 if (!(ff = fopen(
args.filename,
"w"))) {
949 if (fwrite(
value, 1, vlength, ff) < vlength) {
956 if (!(ff = fopen(
args.filename,
"r+"))) {
960 fseeko(ff, 0, SEEK_END);
961 flength = ftello(ff);
964 if (fseeko(ff, offset, SEEK_END)) {
969 if ((offset = ftello(ff)) < 0) {
977 length = flength - offset + length;
979 ast_log(
LOG_ERROR,
"Length '%s' exceeds the file length. No data will be written.\n",
args.length);
985 fseeko(ff, offset, SEEK_SET);
987 ast_debug(3,
"offset=%s/%" PRId64
", length=%s/%" PRId64
", vlength=%" PRId64
", flength=%" PRId64
"\n",
988 S_OR(
args.offset,
"(null)"), offset,
S_OR(
args.length,
"(null)"), length, vlength, flength);
990 if (length == vlength) {
992 if (fwrite(
value, 1, vlength, ff) < vlength) {
998 if (fwrite(
value, 1, vlength, ff) < vlength) {
1002 if (truncate(
args.filename, offset + vlength)) {
1005 }
else if (length > vlength) {
1009 if (fwrite(
value, 1, vlength, ff) < vlength) {
1012 fseeko(ff, length - vlength, SEEK_CUR);
1013 while ((cur = ftello(ff)) < flength) {
1014 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1017 fseeko(ff, cur + vlength - length, SEEK_SET);
1018 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1022 if (fseeko(ff, cur +
sizeof(fbuf), SEEK_SET) < 0) {
1028 if (truncate(
args.filename, flength - (length - vlength))) {
1034 off_t lastwritten = flength + vlength - length;
1037 fseeko(ff, flength -
sizeof(fbuf), SEEK_SET);
1038 while (offset < ftello(ff)) {
1039 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1047 fseeko(ff, vlength - length -
sizeof(fbuf), SEEK_CUR);
1050 lastwritten = ftello(ff);
1052 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1058 if (lastwritten < offset +
sizeof(fbuf)) {
1067 fseeko(ff, 2 *
sizeof(fbuf) + vlength - length, SEEK_CUR);
1071 if (fseeko(ff, offset + length, SEEK_SET)) {
1072 ast_log(
LOG_WARNING,
"Unable to seek to %" PRId64
" + %" PRId64
" != %" PRId64
"?)\n", offset, length, ftello(ff));
1076 ast_debug(1,
"Reading at %" PRId64
"\n", ftello(ff));
1077 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1080 fseek(ff, offset, SEEK_SET);
1082 if (fwrite(
value, 1, vlength, ff) < vlength) {
1085 off_t curpos = ftello(ff);
1086 foplen = lastwritten - curpos;
1087 if (fwrite(fbuf, 1, foplen, ff) < foplen) {
1097 if (
args.argc == 5) {
1098 if (tolower(
args.format[0]) ==
'u') {
1100 }
else if (tolower(
args.format[0]) ==
'm') {
1102 }
else if (tolower(
args.format[0]) ==
'd') {
1111 if (strchr(
args.options,
'a')) {
1113 if (!(ff = fopen(
args.filename,
"a"))) {
1117 if (fwrite(
value, 1, vlength, ff) < vlength) {
1123 }
else if (offset == 0 && length ==
LLONG_MAX) {
1126 if (!(ff = fopen(
args.filename,
"w"))) {
1130 if (fwrite(
value, 1, vlength, ff) < vlength) {
1135 if ((truncsize = ftello(ff)) < 0) {
1139 if (truncsize >= 0 && truncate(
args.filename, truncsize)) {
1144 int64_t offset_offset = (offset == 0 ? 0 : -1), length_offset = -1, flength, i, current_length = 0;
1145 char dos_state = 0, fbuf[4096];
1147 if (offset < 0 && length < offset) {
1149 ast_log(
LOG_ERROR,
"Length cannot specify a position prior to the offset\n");
1153 if (!(ff = fopen(
args.filename,
"r+"))) {
1158 if (fseek(ff, 0, SEEK_END)) {
1163 if ((flength = ftello(ff)) < 0) {
1170 if (offset < 0 || length < 0) {
1172 for (i = (flength /
sizeof(fbuf)) *
sizeof(fbuf); i >= 0; i -=
sizeof(fbuf)) {
1174 if (fseeko(ff, i, SEEK_SET)) {
1177 if (i +
sizeof(fbuf) >= flength) {
1178 memset(fbuf, 0,
sizeof(fbuf));
1180 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1185 for (pos = fbuf +
sizeof(fbuf) - 1; pos >= fbuf; pos--) {
1188 if (length < 0 && count * -1 == length) {
1189 length_offset = i + (pos - fbuf);
1190 }
else if (offset < 0 && count * -1 == (offset - 1)) {
1192 if (newline_format ==
FF_DOS) {
1193 offset_offset = i + (pos - fbuf) + 2;
1195 offset_offset = i + (pos - fbuf) + 1;
1200 if ((offset < 0 && offset_offset >= 0) || (offset >= 0 && length_offset >= 0)) {
1205 if (offset < 0 && offset_offset < 0 && offset == count * -1) {
1213 fseek(ff, 0, SEEK_SET);
1214 for (i = 0; i < flength; i +=
sizeof(fbuf)) {
1216 if (i +
sizeof(fbuf) >= flength) {
1217 memset(fbuf, 0,
sizeof(fbuf));
1219 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1224 for (pos = fbuf; pos < fbuf +
sizeof(fbuf); pos++) {
1227 if (count == offset) {
1228 offset_offset = i + (pos - fbuf) + 1;
1232 if (offset_offset >= 0) {
1238 if (offset_offset < 0) {
1245 length_offset = offset_offset;
1247 length_offset = flength;
1251 if (length_offset < 0) {
1252 fseeko(ff, offset_offset, SEEK_SET);
1253 for (i = offset_offset; i < flength; i +=
sizeof(fbuf)) {
1255 if (i +
sizeof(fbuf) >= flength) {
1256 memset(fbuf, 0,
sizeof(fbuf));
1258 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1263 for (pos = fbuf; pos < fbuf +
sizeof(fbuf); pos++) {
1266 if (current_length == length) {
1267 length_offset = i + (pos - fbuf) + 1;
1271 if (length_offset >= 0) {
1275 if (length_offset < 0) {
1277 ast_debug(3,
"Exceeds length of file? length=%" PRId64
", count=%" PRId64
", flength=%" PRId64
"\n", length, current_length, flength);
1278 length_offset = flength;
1283 if (length_offset - offset_offset == vlength + (strchr(
args.options,
'd') ? 0 : strlen(
format2term(newline_format)))) {
1285 fseeko(ff, offset_offset, SEEK_SET);
1286 if (fwrite(
value, 1, vlength, ff) < vlength) {
1292 }
else if (length_offset - offset_offset > vlength + (strchr(
args.options,
'd') ? 0 : strlen(
format2term(newline_format)))) {
1295 int64_t length_length = length_offset - offset_offset;
1296 size_t vlen = vlength + (strchr(
args.options,
'd') ? 0 : strlen(
format2term(newline_format)));
1298 ast_debug(3,
"offset=%s/%" PRId64
", length=%s/%" PRId64
" (%" PRId64
"), vlength=%" PRId64
", flength=%" PRId64
"\n",
1299 args.offset, offset_offset,
args.length, length_offset, length_length, vlength, flength);
1301 fseeko(ff, offset_offset, SEEK_SET);
1302 if (fwrite(
value, 1, vlength, ff) < vlength) {
1306 }
else if (!strchr(
args.options,
'd') && fwrite(
format2term(newline_format), 1, vlen - vlength, ff) < vlen - vlength) {
1311 while ((cur = ftello(ff)) < flength) {
1317 fseeko(ff, length_length - vlen, SEEK_CUR);
1318 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1324 fseeko(ff, cur, SEEK_SET);
1325 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1332 if (truncate(
args.filename, flength - (length_length - vlen))) {
1337 size_t vlen = vlength + (strchr(
args.options,
'd') ? 0 : strlen(
format2term(newline_format)));
1338 int64_t origlen = length_offset - offset_offset;
1339 off_t lastwritten = flength + vlen - origlen;
1341 ast_debug(3,
"offset=%s/%" PRId64
", length=%s/%" PRId64
", vlength=%" PRId64
", flength=%" PRId64
"\n",
1342 args.offset, offset_offset,
args.length, length_offset, vlength, flength);
1344 fseeko(ff, flength -
sizeof(fbuf), SEEK_SET);
1345 while (offset_offset +
sizeof(fbuf) < ftello(ff)) {
1346 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1351 fseeko(ff,
sizeof(fbuf) - vlen - origlen, SEEK_CUR);
1352 if (fwrite(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf)) {
1357 if ((lastwritten = ftello(ff) -
sizeof(fbuf)) < offset_offset +
sizeof(fbuf)) {
1360 fseeko(ff, 2 *
sizeof(fbuf) + vlen - origlen, SEEK_CUR);
1362 fseek(ff, length_offset, SEEK_SET);
1363 if (fread(fbuf, 1,
sizeof(fbuf), ff) <
sizeof(fbuf) && !feof(ff)) {
1368 fseek(ff, offset_offset, SEEK_SET);
1369 if (fwrite(
value, 1, vlength, ff) < vlength) {
1378 off_t curpos = ftello(ff);
1379 foplen = lastwritten - curpos;
1380 if (fwrite(fbuf, 1, foplen, ff) < foplen) {