--agi.h typedef struct agi_command { /* Null terminated list of the words of the command */ char *cmda[AST_MAX_CMD_LEN]; /* Handler for the command (channel, AGI state, # of arguments, argument list). Returns RESULT_SHOWUSAGE for improper arguments */ int (*handler)(struct ast_channel *chan, AGI *agi, int argc, char *argv[]); /* Summary of the command (< 60 characters) */ char *summary; /* Detailed usage information */ char *usage; int dead; AST_LIST_ENTRY(agi_command_ll) list; } agi_command; --res_agi.c AST_RWLIST_HEAD_STATIC(agi_commands, agi_command); static int help_workhorse(int fd, char *match[]) { char fullcmd[80], matchstr[80]; int x; struct agi_command *temp_command; if (match) ast_join(matchstr, sizeof(matchstr), match); ast_cli(fd, "%5.5s %20.20s %s\n","Dead","Command","Description"); AST_RWLIST_RDLOCK(&agi_commands); AST_RWLIST_TRAVERSE(&agi_commands, temp_command, list) { if (!temp_command->cmda[0]) break; // Hide commands that start with '_' if ((temp_command->cmda[0])[0] == '_') continue; ast_join(fullcmd, sizeof(fullcmd), temp_command->cmda); if (match && strncasecmp(matchstr, fullcmd, strlen(matchstr))) continue; ast_cli(fd, "%5.5s %20.20s %s\n", temp_command->dead ? "Yes" : "No" , fullcmd, temp_command->summary); } AST_RWLIST_UNLOCK(&agi_commands); return 0; }