C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
amort.c File Reference

Installment Loan Amortization. More...

#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
Include dependency graph for amort.c:

Go to the source code of this file.

Macros

#define _(String)
#define _GNU_SOURCE
#define bindtextdomain(Package, Directory)
#define N_(String)
#define textdomain(Domain)

Functions

int main (int argc, char **argv)
 Capture the current terminal settings for later restoration.
void print_totals (Amort *)

Variables

char month [12][4]

Detailed Description

Installment Loan Amortization.

Author
Bill Waller Copyright (c) 2026 MIT License billx.nosp@m.wall.nosp@m.er@gm.nosp@m.ail..nosp@m.com
Date
2026-05-05

Definition in file amort.c.

Macro Definition Documentation

◆ _

#define _ ( String)
Value:
Definition cm.h:409
Examples
/usr/local/src/C-Menu/src/enterchr.c, and /usr/local/src/C-Menu/src/enterstr.c.

Definition at line 23 of file amort.c.

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 9 of file amort.c.

◆ bindtextdomain

#define bindtextdomain ( Package,
Directory )

Definition at line 26 of file amort.c.

◆ N_

#define N_ ( String)
Value:

Definition at line 24 of file amort.c.

◆ textdomain

#define textdomain ( Domain)

Definition at line 25 of file amort.c.

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Capture the current terminal settings for later restoration.

Main function for rsh.

iloan is a trivial application to demonstrate how a command-line program can be integrated into C-Menu Form with simple file, argument, or pipe i-o.

allows the user to enter a string in cooked mode

can be used in scripts to get a single character response from a user. For example: response=$(./enterchr "Enter Y or N: ") if [ "$response" = "Y" ]; then echo "You entered Yes" else echo "You entered No" fi This function saves the current terminal settings into a global variable so that they can be restored later. It should be called before modifying the terminal settings to ensure that the original settings can be restored when the program exits or is interrupted.

allows line editing and other features writes the prompt to stderr and the user's input to stdout handles signals to ensure that the terminal settings are restored if the program is interrupted.

Positional arguments: present_value The present value of the loan (the amount borrowed). number_of_payments The total number of payments to be made. interest_rate The annual interest rate (as a percentage). payment_amount The amount of each payment. The program calculates the missing value based on the three provided values. For example, if the present value, number of payments, and interest rate are provided, it will calculate the payment amount. If the present value, interest rate, and payment amount are provided, it will calculate the number of payments, and so on. The program can be used in a non-interactive way by passing the four values as arguments, with the value to be calculated set to 0. For example, to calculate the payment amount for a $10,000 loan with a 5% annual interest rate and 60 monthly payments, you could run:

iloan 10000 60 5 0

This is proof-of-concept code, and is not intended for production use. It is not designed to be robust, and does not handle all edge cases or input errors. It is intended solely to demonstrate how a simple command-line program can be integrated into C-Menu Form. In the future, more sophisticated abstractions, such as async event handlers, serialization, rpc, database, and a standardized plugin interface will be integrated into C-Menu. Feel free to modify and enhance this code as needed, but please do not use it in production without proper testing and validation. It is provided as-is without any warranty or support. Use at your own risk.

Parameters
argcArgument count
argvArgument vector

If executed as 'rsh', this program sets the user ID and group ID to 0 (root) and then executes the user's default shell (or /usr/bin/bash if SHELL is not set) with the provided arguments. If no arguments are given, it runs the shell in interactive mode. To work properly, this program must be compiled and set with the setuid bit:

$ sudo -s
cc rsh.c -o rsh
sudo chown root:root rsh
sudo chmod 4755 rsh
exit

to verify proper operation:

$ rsh
$ whoami
root

Definition at line 41 of file amort.c.

41 {
42 setlocale(LC_NUMERIC, "");
43 if (argc > 1 &&
44 ((strcmp(argv[1], _("--help")) == 0 || strcmp(argv[1], "-h") == 0) ||
45 argc < 5)) {
46 printf(_("Usage: amort [present_value][number_of_payments] [interest_rate][payment_amount][yyyy-mm-dd]\n\n"));
47 exit(EXIT_SUCCESS);
48 }
49 struct tm tm;
50 Amort *amort = malloc(sizeof(Amort));
51 sscanf(argv[1], _("%lf"), &amort->pv);
52 sscanf(argv[2], _("%lf"), &amort->n);
53 sscanf(argv[3], _("%lf"), &amort->i);
54 sscanf(argv[4], _("%lf"), &amort->pmt);
55 if (amort->pv == 0 || amort->n == 0 || amort->i == 0 || amort->pmt == 0 ||
56 argv[5][0] == '\0') {
57 fprintf(stderr, _("Error: All arguments must be non-zero.\n"));
58 exit(EXIT_FAILURE);
59 }
60 amort->interest = amort->pv * amort->i / 1200;
61 if (amort->interest > amort->pmt) {
62 fprintf(stderr, _("Error: Payment amount less than interest\n"));
63 exit(EXIT_FAILURE);
64 }
65 memset(&tm, 0, sizeof(tm));
66 if (strptime(argv[5], _("%Y-%m-%d"), &tm) == NULL)
67 if (strptime(argv[5], _("%Y%m%d"), &tm) == NULL)
68 printf(_("Error: Invalid date format. Use yyyy-mm-dd or yyyymmdd.\n")),
69 exit(EXIT_FAILURE);
70 amort->year_total_interest = 0;
71
72 printf("First Payment: %04d-%02d-%02d\n\n", tm.tm_year + 1900,
73 tm.tm_mon + 1, tm.tm_mday);
74 printf(_(" Per Mth Year Balance Payment Principal Interest\n"));
75 printf(_("---- --- ---- ------------ ---------- ---------- ----------\n"));
76 int m = 0;
77 for (int x = 0; x < amort->n; x++) {
78 if (amort->pv <= 0)
79 break;
80 m = (x + tm.tm_mon) % 12;
81 int y = ((x + tm.tm_mon) / 12) + tm.tm_year + 1900;
82 amort->interest = amort->pv * amort->i / 1200;
83 amort->year_total_interest += amort->interest;
84 if (amort->pv + amort->interest < amort->pmt) {
85 amort->pmt = amort->pv + amort->interest;
86 amort->principal = amort->pv;
87 } else
88 amort->principal = amort->pmt - amort->interest;
89 amort->pv -= amort->principal;
90 printf("%4d %4s %4d %'12.2f %'10.2f %'10.2f %'10.2f\n", x + 1, month[m],
91 y, amort->pv, amort->pmt, amort->principal, amort->interest);
92 if (m == 11)
93 print_totals(amort);
94 }
95 if (m != 11)
96 print_totals(amort);
97 free(amort);
98 return EXIT_SUCCESS;
99}
#define _(String)
Definition amort.c:23
void print_totals(Amort *)
Definition amort.c:100
char month[12][4]
Definition amort.c:28

References month, and print_totals().

Here is the call graph for this function:

◆ print_totals()

void print_totals ( Amort * amort)

Definition at line 100 of file amort.c.

100 {
101 printf(_(" ----------\n"));
102 printf(_(" %'10.2f\n"),
103 amort->year_total_interest);
104 printf(_(" ==========\n\n"));
105 amort->year_total_interest = 0;
106}

Referenced by main().

Here is the caller graph for this function:

Variable Documentation

◆ month

char month
Initial value:
= {_("Jan"), _("Feb"), _("Mar"), _("Apr"), _("May"), _("Jun"),
_("Jul"), _("Aug"), _("Sep"), _("Oct"), _("Nov"), _("Dec")}

Definition at line 28 of file amort.c.

28 {_("Jan"), _("Feb"), _("Mar"), _("Apr"), _("May"), _("Jun"),
29 _("Jul"), _("Aug"), _("Sep"), _("Oct"), _("Nov"), _("Dec")};

Referenced by main().