Decoded: pinky (coreutils)

[Back to Project Main Page]

Note: This page explores the design of command-line utilities. It is not a user guide.
[No GNU Manual entry] [No POSIX requirement] [Linux man] [No FreeBSD requirement]

Logical flow of pinky command (coreutils)

Summary

pinky - lightweight finger

[Source] [Code Walkthrough]

Lines of code: 603
Principal syscall: None
Support syscalls: stat()
Options: 11 (9 short, 2 long)

This utility was introduced in the 1990s as a local finger
Added to Fileutils in August 1997 [First version]
Number of revisions: 101

The pinky utility relies on data from either the passwd file or the utmp file to output user information

Helpers:
  • count_ampersands() - Counts the number of amperands in an input string
  • create_fullname() - Allocates a string containing the user's full name
  • idle_string() - Creates a string containing a time difference
  • long_pinky() - Peforms pinky with long output for a user(s) (-l option)
  • print_entry() - Prints entry from a utmp structure
  • print_heading() - Prints data headers for utmp entries
  • print_long_entry() - Prints a verbose entry from a utmp structure
  • scan_entries() - Walks through each user in utmp and prints the entry
  • short_pinky() - Peforms pinky with short output (-s option)
  • time_string() - Returns the time string from a utmp structure
External non-standard helpers:
  • canon_host() - Returns the canonical hostname if possible, NULL if not
  • die() - Exit with mandatory non-zero error and message to stderr
  • error() - Outputs error message to standard error with possible process termination
  • getpwnam() - Gets an entry from the password file by name
  • localtime() - Returns a time_t struct with system time
  • read_utmp() - Retrives data from the system utmp file (from gnulib)

Setup

pinky defines seven global flags to hold execution behaviors. By default all are true and options suppress output:

  • do_short_format - Flag if we're using short form (-s or -l)
  • include_fullname - Flag to display user's full name (-w, -i, -q)
  • include_heading - Flag to display headings (-f)
  • include_home_and_shell - Flag to display home direcory and shell type (-b)
  • include_idle - Flag to show idle time (-q)
  • include_plan - Flag to show user's .plan file (-p)
  • include_project - Flag to show user's project file (-h)

main() initializes the following:

  • n_users - The number of users requested to display output
  • optc - The first character of the next option to parse

Parsing

Parsing for pinky lets the user decide which output details they would like to suppress to include: name, shell type, home directory, plan file, and project file. The user may control output format (long or short)

Parsing failures

Two failure cases are explicitly checked:

  • Requesting long form output without a target user
  • Using an unknown option

This failure result in a short error message followed by the usage instructions.


Execution

Executing pinky follows two distinct paths, depending on the desired output format (short or long). The data source varies in both cases.

Short format execution:

  • Read system utmp file in to a buffer
  • Define time format and print column headings
  • Loop through each entry and print the requested fields
  • Free the utmp buffer

Long format execution:

  • Loop through the provided user names and...
    • Pull the passwd entry with getpwnam()
    • Print all desired fields

The single failure case is if we are unable to read utmp file in short format mode. In long format mode, a non-existing user simply has no output. The failure outputs an error message to STDERR and returns without displaying usage help


[Back to Project Main Page]