1

C++ を使用して ftp サーバーをプログラミングしていますが、ファイルに関するすべての情報を次の形式で取得できる必要があります。

sent: drwxr-xr-x 1000 ubuntu ubuntu 4096 May 16 11:44 Package-Debug.bash

クライアントに送信できるようにします。部分的には成功しましたが、いくつかの問題に遭遇しました。ここに私のコードの一部があります:

void Communication::LISTCommand() {
DIR *directory;
struct dirent *ent;
char path[100];
strcpy(path, this->path.c_str());  //this->path can be different from current working path

/*if (chdir(path) == -1) {
    perror("Error while changing the working directory ");
    close(clie_sock);
    exit(1);
}*/

directory = opendir(path);
struct tm* clock;
struct stat attrib;
struct passwd *pw;
struct group *gr;
string line;
char file_info[1000];

.....

while ((ent = readdir(directory)) != NULL) {
    line.clear();
    stat(ent->d_name, &attrib);

    clock = gmtime(&(attrib.st_mtime));
    pw = getpwuid(attrib.st_uid);
    gr = getgrgid(attrib.st_gid);
    if (S_ISDIR(attrib.st_mode))
        line.append(1, 'd');
    else line.append(1, '-');
    if (attrib.st_mode & S_IRUSR)
        line.append(1, 'r');
    else line.append(1, '-');
    if (attrib.st_mode & S_IWUSR)
        line.append(1, 'w');
    else line.append(1, '-');
    if (attrib.st_mode & S_IXUSR)
        line.append(1, 'x');
    else line.append(1, '-');
    if (attrib.st_mode & S_IRGRP)
        line.append(1, 'r');
    else line.append(1, '-');
    if (attrib.st_mode & S_IWGRP)
        line.append(1, 'w');
    else line.append(1, '-');
    if (attrib.st_mode & S_IXGRP)
        line.append(1, 'x');
    else line.append(1, '-');
    if (attrib.st_mode & S_IROTH)
        line.append(1, 'r');
    else line.append(1, '-');
    if (attrib.st_mode & S_IWOTH)
        line.append(1, 'w');
    else line.append(1, '-');
    if (attrib.st_mode & S_IXOTH)
        line.append("x ");
    else line.append("- ");

    sprintf(file_info, "%s%d %s %s %d %s %d %02d:%02d %s\r\n", line.c_str(), pw->pw_uid,
            pw->pw_name, gr->gr_name, (int) attrib.st_size, getMonth(clock->tm_mon).c_str(),
            clock->tm_mday, clock->tm_hour, clock->tm_min, ent->d_name);

    if (send(c_data_sock, file_info, strlen(file_info), 0) == -1) {
        perror("Error while writing ");
        close(clie_sock);
        exit(1);
    }

    cout << "sent: " << file_info << endl;
}

.....

}

パス変数が現在の作業パスと異なる場合、このコードは機能しません。Valgrind は、初期化されていない値などに依存する多くのジャンプがあり、ファイルのリストに間違った値が含まれていると述べています - ファイル名とサイズだけが正しいです。現在の作業ディレクトリをパス変数の内容に変更すると、エラーは報告されませんが、ファイル リストにはまだ間違った情報が含まれています。私のコードの何が問題なのか本当にわかりませんので、どんな助けでも大歓迎です。

4

1 に答える 1

1

あなたがするとき

stat(ent->d_name, &attrib);

ent->d_nameフルパスではなく、ファイル名のみが含まれていることに注意してください。したがって、プログラムの現在のディレクトリとは異なるディレクトリにあるファイルを一覧表示する場合は、使用するフル パスを作成する必要があります。

最も簡単な解決策は、おそらく次のようなことをすることです

std::string full_path = path;
full_path += '/';
full_path += ent->d_name;

if (stat(full_path.c_str(), &attrib) != -1)
{
    // Do your stuff here
}
于 2013-05-16T12:19:15.030 に答える