This function is normally called by the sender, but the receiving side also * calls it from get_dirlist() with f set to -1 so that we just construct the * file list in memory without sending it over the wire. Also, get_dirlist() * might call this with f set to -2, which also indicates that local filter * rules should be ignored. */
| 1854 | * might call this with f set to -2, which also indicates that local filter |
| 1855 | * rules should be ignored. */ |
| 1856 | static void send_directory(int f, struct file_list *flist, char *fbuf, int len, |
| 1857 | int flags) |
| 1858 | { |
| 1859 | struct dirent *di; |
| 1860 | unsigned remainder; |
| 1861 | char *p; |
| 1862 | DIR *d; |
| 1863 | int divert_dirs = (flags & FLAG_DIVERT_DIRS) != 0; |
| 1864 | int start = flist->used; |
| 1865 | int filter_level = f == -2 ? SERVER_FILTERS : ALL_FILTERS; |
| 1866 | |
| 1867 | assert(flist != NULL); |
| 1868 | |
| 1869 | if (!(d = opendir(fbuf))) { |
| 1870 | if (errno == ENOENT) { |
| 1871 | if (am_sender) /* Can abuse this for vanished error w/ENOENT: */ |
| 1872 | interpret_stat_error(fbuf, True); |
| 1873 | return; |
| 1874 | } |
| 1875 | if (errno == ENOTDIR && (flags & FLAG_PERHAPS_DIR)) |
| 1876 | return; |
| 1877 | io_error |= IOERR_GENERAL; |
| 1878 | rsyserr(FERROR_XFER, errno, "opendir %s failed", full_fname(fbuf)); |
| 1879 | return; |
| 1880 | } |
| 1881 | |
| 1882 | p = fbuf + len; |
| 1883 | if (len == 1 && *fbuf == '/') |
| 1884 | remainder = MAXPATHLEN - 1; |
| 1885 | else if (len < MAXPATHLEN-1) { |
| 1886 | *p++ = '/'; |
| 1887 | *p = '\0'; |
| 1888 | remainder = MAXPATHLEN - (len + 1); |
| 1889 | } else |
| 1890 | remainder = 0; |
| 1891 | |
| 1892 | for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) { |
| 1893 | unsigned name_len; |
| 1894 | char *dname = d_name(di); |
| 1895 | if (dname[0] == '.' && (dname[1] == '\0' |
| 1896 | || (dname[1] == '.' && dname[2] == '\0'))) |
| 1897 | continue; |
| 1898 | name_len = strlcpy(p, dname, remainder); |
| 1899 | if (name_len >= remainder) { |
| 1900 | char save = fbuf[len]; |
| 1901 | fbuf[len] = '\0'; |
| 1902 | io_error |= IOERR_GENERAL; |
| 1903 | rprintf(FERROR_XFER, |
| 1904 | "filename overflows max-path len by %u: %s/%s\n", |
| 1905 | name_len - remainder + 1, fbuf, dname); |
| 1906 | fbuf[len] = save; |
| 1907 | continue; |
| 1908 | } |
| 1909 | if (dname[0] == '\0') { |
| 1910 | io_error |= IOERR_GENERAL; |
| 1911 | rprintf(FERROR_XFER, |
| 1912 | "cannot send file with empty name in %s\n", |
| 1913 | full_fname(fbuf)); |
no test coverage detected