#include "builtins.h"
#include <errno.h>
#include <limits.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "sish.h"
bool
is_builtin(const char* cmd)
{
return strcmp(cmd, "cd") == 0 || strcmp(cmd, "echo") == 0 ||
strcmp(cmd, "exit") == 0;
}
int
split_builtin_args(char* cmd_and_args, char** argv_out)
{
int count = 0;
char* tok = strtok(cmd_and_args, " ");
while (tok != NULL && count < MAX_ARGS - 1)
{
argv_out[count] = tok;
count++;
tok = strtok(NULL, " ");
}
argv_out[count] = NULL;
return count;
}
int
sish_echo(char** token_args, int token_args_count)
{
for (int i = 1; i < token_args_count; i++)
{
char* word = token_args[i];
/* handled elsewhere */
if (IS_SHELL_SPECIAL(word))
{
break;
}
printf("%s", word);
// join with a space if not last or a shell special
if (i < token_args_count - 1 && !IS_SHELL_SPECIAL(token_args[i + 1]))
{
printf(" ");
}
}
printf("\n");
return 0;
}
void
sish_exit(int status)
{
exit(status);
}
int
sish_cd(char** token_args, int token_args_count)
{
if (token_args_count > 2)
{
fprintf(stderr, "%s: cd: too many arguments.\n", GET_PROGNAME_ERR);
return 1;
}
const char* target = NULL;
/* cd or cd ~. home directory*/
if (token_args_count == 1 || strcmp(token_args[1], "~") == 0)
{
target = getenv("HOME");
if (target == NULL)
{
struct passwd* pw = getpwuid(getuid());
if (pw == NULL)
{
fprintf(
stderr,
"%s: cd: cannot change directory to %s: getpwuid: %s.\n",
GET_PROGNAME_ERR, token_args[1], strerror(errno));
return 1;
}
target = pw->pw_dir;
}
}
else
{
/* try whatever the user gave us */
target = token_args[1];
}
if (chdir(target) == -1)
{
fprintf(stderr, "%s: cd: cannot change directory to %s: %s.\n",
GET_PROGNAME_ERR, target, strerror(errno));
return 1;
}
return 0;
}