-
Notifications
You must be signed in to change notification settings - Fork 10
Add datemotd module for date-based MOTD messages #136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: unreal6
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,280 @@ | ||||||||||||||||||||||||||||||||
| /* GPL v3 | ||||||||||||||||||||||||||||||||
| Valware © 2025 | ||||||||||||||||||||||||||||||||
| Shows a specific message in the MOTD on a specific date | ||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||
| /*** <<<MODULE MANAGER START>>> | ||||||||||||||||||||||||||||||||
| module | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| documentation "https://github.com/ValwareIRC/valware-unrealircd-mods/blob/main/datemotd/README.md"; | ||||||||||||||||||||||||||||||||
| troubleshooting "In case of problems, check the documentation or e-mail me at [email protected]"; | ||||||||||||||||||||||||||||||||
| min-unrealircd-version "6.2.2"; | ||||||||||||||||||||||||||||||||
| max-unrealircd-version "6.*"; | ||||||||||||||||||||||||||||||||
| post-install-text | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| "The module is installed. Now all you need to do is add a loadmodule line:"; | ||||||||||||||||||||||||||||||||
| "loadmodule \"third/datemotd\";"; | ||||||||||||||||||||||||||||||||
| "Configure the block as described in the documentation."; | ||||||||||||||||||||||||||||||||
| "Once you're good to go, type ./unrealircd rehash"; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| *** <<<MODULE MANAGER END>>> | ||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| #include "unrealircd.h" | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| #define DATEMOTD_CONF "datemotd" | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| struct datemotd_item { | ||||||||||||||||||||||||||||||||
| char *name; | ||||||||||||||||||||||||||||||||
| char *file; | ||||||||||||||||||||||||||||||||
| char *date; // NEW: date in format YYYY-MM-DD | ||||||||||||||||||||||||||||||||
| struct datemotd_item *next; | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| struct datemotd_conf { | ||||||||||||||||||||||||||||||||
| struct datemotd_item *datemotds; | ||||||||||||||||||||||||||||||||
| unsigned short int got_datemotd; | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| static struct datemotd_conf datemotd_conf; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| void set_config_defaults(void); | ||||||||||||||||||||||||||||||||
| void free_config(void); | ||||||||||||||||||||||||||||||||
| int datemotd_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *errs); | ||||||||||||||||||||||||||||||||
| int datemotd_configrun(ConfigFile *cf, ConfigEntry *ce, int type); | ||||||||||||||||||||||||||||||||
| int motd_hook(Client *client); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| ModuleHeader MOD_HEADER = { | ||||||||||||||||||||||||||||||||
| "third/datemotd", | ||||||||||||||||||||||||||||||||
| "1.1", | ||||||||||||||||||||||||||||||||
| "Shows a specific message in the MOTD on a specific date", | ||||||||||||||||||||||||||||||||
| "Valware", | ||||||||||||||||||||||||||||||||
| "unrealircd-6" | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| static int is_valid_date_string(const char *datestr) | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| if (!datestr) return 0; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // YYYY-MM-DD | ||||||||||||||||||||||||||||||||
| if (isdigit(datestr[0])) { | ||||||||||||||||||||||||||||||||
| int y, m, d; | ||||||||||||||||||||||||||||||||
| if (sscanf(datestr, "%d-%d-%d", &y, &m, &d) != 3) | ||||||||||||||||||||||||||||||||
| return 0; | ||||||||||||||||||||||||||||||||
| if (y < 1970 || m < 1 || m > 12 || d < 1 || d > 31) | ||||||||||||||||||||||||||||||||
| return 0; | ||||||||||||||||||||||||||||||||
|
Comment on lines
+62
to
+67
|
||||||||||||||||||||||||||||||||
| return 1; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // Weekday names | ||||||||||||||||||||||||||||||||
| const char *days_short[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; | ||||||||||||||||||||||||||||||||
| const char *days_long[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| char lower_input[16]; | ||||||||||||||||||||||||||||||||
| int i; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
| int i; | |
| int i; | |
| // Reject input longer than buffer size (15 chars) | |
| if (strlen(datestr) > sizeof(lower_input) - 1) | |
| return 0; |
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Variable j is declared in the for loop initialization, which requires C99 or later. While this is likely supported, ensure consistency with the rest of the codebase's C standard usage. The same pattern appears on line 88.
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The weekday name arrays and lowercase conversion logic are duplicated in three places: is_valid_date_string (lines 72-90), is_today (lines 112-128), and the arrays appear again in is_today. Consider extracting this into a helper function or using constants to avoid code duplication and reduce maintenance burden.
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
localtime() returns a pointer to static internal storage that may be overwritten by subsequent calls. While this is likely safe in this specific context, it's not thread-safe. Consider using localtime_r() for thread safety if the UnrealIRCd framework supports multi-threaded operations.
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no error logging when the file cannot be opened. Users won't know why their configured datemotd isn't being displayed. Consider logging a warning or error message to help with troubleshooting.
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The file reading logic doesn't handle lines that don't end with a newline character (e.g., the last line of a file). If the last line doesn't have a trailing newline, line[len-1] won't be '\n', and the line will be sent with its content intact but won't be processed through the newline removal logic. This could lead to inconsistent behavior. Consider also sending lines that don't end with newlines.
| sendnumeric(client, RPL_MOTD, line); | |
| } | |
| } | |
| sendnumeric(client, RPL_MOTD, line); |
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment "NEW" is a development artifact that should be removed before finalizing the code. This type of comment is useful during development but serves no purpose in the final codebase.
| safe_free(p->date); // NEW | |
| safe_free(p->date); |
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The memset after safe_alloc is redundant. The safe_alloc function typically already zeros the allocated memory (it's a common pattern in C codebases to have allocation functions that zero memory). Verify if this is the case in the UnrealIRCd codebase and remove the redundant memset if so.
| memset(new_item, 0, sizeof(*new_item)); | |
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The safe_strdup macro is being used with a side effect pattern. If any of the safe_strdup calls fail (return NULL or similar), the new_item will be partially initialized and still added to the list, potentially causing issues later. Consider validating that all required fields are properly set before adding the item to the list.
| new_item->next = datemotd_conf.datemotds; | |
| datemotd_conf.datemotds = new_item; | |
| } | |
| // Validate that all required fields are set | |
| if (!new_item->name || !new_item->file || !new_item->date) { | |
| // Free any allocated fields and the struct itself | |
| if (new_item->name) free(new_item->name); | |
| if (new_item->file) free(new_item->file); | |
| if (new_item->date) free(new_item->date); | |
| free(new_item); | |
| config_error("datemotd: 'item' block is missing required fields or memory allocation failed"); | |
| continue; | |
| } | |
| new_item->next = datemotd_conf.datemotds; | |
| datemotd_conf.datemotds = new_item; |
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment "NEW: hook to send MOTD only on the matching date" is a development artifact that should be removed. This type of comment is useful during development but serves no purpose in the final codebase.
| // NEW: hook to send MOTD only on the matching date |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment "NEW: date in format YYYY-MM-DD" is incomplete and misleading. The date field actually supports both YYYY-MM-DD format and weekday names (e.g., "Monday", "Mon"). Update the comment to reflect all supported formats.