Old/new editing is intentionally conservative: exact old text must be unique. * For large replacements, old may contain one [upto] marker: the head must be * unique, and the tail must be unique after that head before the whole span is * replaced. */
| 6265 | agent_buf_puts(&b, "Tool error: opendir failed: "); |
| 6266 | agent_buf_puts(&b, strerror(errno)); |
| 6267 | agent_buf_puts(&b, "\n"); |
| 6268 | return agent_buf_take(&b); |
| 6269 | } |
| 6270 | agent_buf out = {0}; |
| 6271 | char hdr[PATH_MAX + 64]; |
| 6272 | snprintf(hdr, sizeof(hdr), "%s:\n", path); |
| 6273 | agent_buf_puts(&out, hdr); |
| 6274 | struct dirent *de; |
| 6275 | int shown = 0; |
| 6276 | while ((de = readdir(dir)) != NULL && shown < 300) { |
| 6277 | if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) continue; |
| 6278 | char full[PATH_MAX]; |
| 6279 | snprintf(full, sizeof(full), "%s/%s", path, de->d_name); |
| 6280 | struct stat st; |
| 6281 | if (lstat(full, &st) != 0) continue; |
| 6282 | char type = S_ISDIR(st.st_mode) ? 'd' : |
| 6283 | S_ISLNK(st.st_mode) ? 'l' : |
| 6284 | S_ISREG(st.st_mode) ? '-' : '?'; |
| 6285 | char line[PATH_MAX + 96]; |
| 6286 | snprintf(line, sizeof(line), "%c %10lld %s%s\n", type, |
| 6287 | (long long)st.st_size, de->d_name, S_ISDIR(st.st_mode) ? "/" : ""); |
| 6288 | agent_buf_puts(&out, line); |
| 6289 | shown++; |
| 6290 | } |
| 6291 | if (de) agent_buf_puts(&out, "... more entries omitted ...\n"); |
| 6292 | closedir(dir); |
| 6293 | return agent_buf_take(&out); |
| 6294 | } |
| 6295 | |
| 6296 | /* ============================================================================ |
| 6297 | * Edit And Search Tools |
| 6298 | * ============================================================================ |
| 6299 | */ |
| 6300 | |
| 6301 | static int agent_write_file_bytes(const char *path, const char *data, size_t len, |
| 6302 | char *err, size_t errlen) { |
| 6303 | FILE *fp = fopen(path, "wb"); |
| 6304 | if (!fp) { |
| 6305 | snprintf(err, errlen, "open %s: %s", path, strerror(errno)); |
| 6306 | return -1; |
| 6307 | } |
| 6308 | size_t wr = fwrite(data, 1, len, fp); |
| 6309 | if (wr != len) { |
| 6310 | snprintf(err, errlen, "write %s: %s", path, strerror(errno)); |
| 6311 | fclose(fp); |
no test coverage detected