cybersecurity · beginner · ~20 min

Pattern-match log file rotation candidates

Strict prefix matching.

Challenge

Match rotated log files against a base name — the lookup an incident-response tool uses to find the right archive (app.log.1, app.log.2024-01-15, ...).

Task

Implement int is_rotated_log(const char *name, const char *candidate) that returns 1 if candidate is name itself or a rotation of it, else 0.

A candidate matches when it is either:

  • exactly equal to name, OR
  • name followed by a literal . followed by at least one more character.

Input

  • name: the base log name (e.g. app.log).
  • candidate: a filename to test.

Output

Returns int: 1 if candidate matches the rule above, else 0.

Example

is_rotated_log("app.log", "app.log")             ->   1   (exact)
is_rotated_log("app.log", "app.log.1")           ->   1
is_rotated_log("app.log", "app.log.2024-01-15.gz") ->   1
is_rotated_log("app.log", "app.log.")            ->   0   (nothing after the dot)
is_rotated_log("app.log", "app.log2")            ->   0   (no separating dot)
is_rotated_log("app.log", "unrelated")           ->   0

Edge cases

  • A trailing dot with no suffix (app.log.) does not match.
  • app.log2 does not match — the dot separator is required.
  • A candidate shorter than name cannot match.

Rules

  • No regex — compare the strings directly.

Why this matters

A common pattern in incident response: scan a directory listing for rotated log files (app.log.1, app.log.2024-01-15, etc.) so you can pull the right archive. Building a simple matcher teaches glob-like patterns the disciplined way.

Input format

Two NUL-terminated strings: the base name and a candidate filename.

Output format

An int: 1 if candidate is name or a rotation of it, else 0.

Constraints

No regex; require a literal . plus at least one suffix character for a rotation.

Starter code

int is_rotated_log(const char *name, const char *candidate) { /* TODO */ return 0; }

Common mistakes

Treating app.log2 as a rotation (must require literal . between name and suffix); accepting app.log. with no trailing chars (degenerate case).

Edge cases to handle

Exact match. Empty candidate. Candidate shorter than name.

Complexity

O(strlen).

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.