Skip to content

CFE-2986: Added getdir command to cf-net, copies directory and files#6049

Open
SimonThalvorsen wants to merge 1 commit intocfengine:masterfrom
SimonThalvorsen:CFE-2986
Open

CFE-2986: Added getdir command to cf-net, copies directory and files#6049
SimonThalvorsen wants to merge 1 commit intocfengine:masterfrom
SimonThalvorsen:CFE-2986

Conversation

@SimonThalvorsen
Copy link
Contributor

Ticket: CFE-2986
Changelog: Title

@SimonThalvorsen SimonThalvorsen requested a review from larsewi March 2, 2026 10:02
@larsewi larsewi changed the title Added getdir command to cf-net, copies directory and files CFE-2986: Added getdir command to cf-net, copies directory and files Mar 2, 2026
Copy link
Contributor

@larsewi larsewi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nicer if we extended cf-net get to get both files and directories, instead of having two separate sub-commands. Please investigate how rsync does this and try to do it in a similar way here.

@olehermanse
Copy link
Member

olehermanse commented Mar 4, 2026

It would be nicer if we extended cf-net get to get both files and directories, instead of having two separate sub-commands. Please investigate how rsync does this and try to do it in a similar way here.

@larsewi on the other hand, cf-net was written mainly as a protocol testing tool, and the commands mirror their protocol command names. If the GET protocol command in CFEngine network protocol can only GET a file, it might be a bit confusing that cf-net get is something very different.

There is also some advantage to not being too dynamic with this stuff. If you make a CLI that forces the user to specify if they are copying a file or a folder, you can prevent some annoying / confusing situations.

We could for example make a new subcommand, copy;

$ cf-net copy --file promises.cf
Copying file 1.2.3.4:/var/cfengine/masterfiles/promises.cf -> ./promises.cf
$ cf-net copy --file services/
Error: 'services/' does not look like a file, did you mean --directory?
$ cf-net copy --file services/.
Error: 'services/.' does not look like a file, did you mean --directory?
$ cf-net copy --directory services/
Copying directory 1.2.3.4:/var/cfengine/masterfiles/services/ -> ./services/
$ cf-net copy services/
Copying directory 1.2.3.4:/var/cfengine/masterfiles/services/ -> ./services/
$ cf-net copy services
Warning: Ambiguous if 'services' is a file or a directory - consider adding --file or --directory.
Copying directory 1.2.3.4:/var/cfengine/masterfiles/services/ -> ./services/

Copy link
Contributor

@larsewi larsewi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please break this up a little. Maybe a recursive solution would be more elegant given that it is a recursive problem.

cf-net/cf-net.c Outdated
filedata->print_stats = opts->print_stats;

filedata->ret = ProtocolStatGet(conn, filedata->remote_file,
filedata->local_file, 0644, filedata->print_stats);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you should use the remote file permissions (available from the ProtocolStat) instead?

cf-net/cf-net.c Outdated
char curr_dir[PATH_MAX];
snprintf(curr_dir, sizeof(curr_dir), "%s/%s", local_dir, curr);

GetFileData *filedata = calloc(1, sizeof(GetFileData));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not need to be heap allocated

cf-net/cf-net.c Outdated
continue;
}

snprintf(filedata->local_file, PATH_MAX, "%s", curr_dir);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check for truncation on all the calls to snprintf

Comment on lines +1053 to +1054
if (specified_path)
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some inconsistent indentation here

cf-net/cf-net.c Outdated
Comment on lines +1034 to +1035
return invalid_command("getdir");
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unreachable break after return

cf-net/cf-net.c Outdated
if (local_dir != NULL)
{
Log(LOG_LEVEL_INFO,
"Warning: multiple occurences of -o in command, "\
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Warning: multiple occurences of -o in command, "\
"Warning: multiple occurrences of -o in command, "\

Log(LOG_LEVEL_ERR, "Failed to get remote file: %s:%s",
conn->this_server, remote_path);
return false;
}

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter conn in CFNetGetWithPerms() is dereferenced without an explicit null-check
}

// Helper: Create local directory path
static bool create_local_dir(const char *local_base, const char *subdir,

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter conn in CFNetGetWithPerms() is dereferenced without an explicit null-check
Ticket: CFE-2986
Changelog: Title

Signed-off-by: Simon Halvorsen <simon.halvorsen@northern.tech>
char *local_dir = NULL;

int argc = 0;
while (args[argc] != NULL)

Check warning

Code scanning / CodeQL

Poorly documented large function Warning

Poorly documented function: fewer than 2% comments for a function of 115 lines.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants