Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jvsardo committed Sep 7, 2013
0 parents commit 80779d1
Show file tree
Hide file tree
Showing 6 changed files with 405 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CC = gcc
FLAGS = -pedantic -Wall -Wextra -std=c99 -o
FILES = cli.c misc.c cmd_mains.c arg_parse.c
EXEC = cli

build : $(FILES)
$(CC) $(FILES) $(FLAGS) $(EXEC)

73 changes: 73 additions & 0 deletions arg_parse.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include "arg_parse.h"

/* this file contains all of the argument parsing funtions that are used
* to interpret the user input. */

int get_argc(char *s)
{
char *sp = s;
int count = 0;

while (*sp != '\0') {
while (isspace(*sp) && *sp != '\0')
sp++;
if (*sp == '\0')
return count;
else
count++;
while (!isspace(*sp) && *sp != '\0')
sp++;
}
return count;
}

char *skip_flag(char *s)
{
while (!isspace(*s) && *s != '\0')
s++;

return s;
}

char **get_args(char *s, int index)
{
char **args, arg[BUFSIZE], *argp;
int i;
args = (char **) malloc (BUFSIZ);

s += index;
_argc = get_argc(s);

for (i = 0; i < _argc; i++) {
argp = arg;
top:
while (isspace(*s))
s++;
if (*s == '-') {
s = skip_flag(s);
_argc--;
goto top;
}
while (!isspace(*s) || *s == '\0')
*argp++ = *s++;

*argp = '\0';
args[i] = strdup(arg);
}

return args;
}

char *get_flags(char *buf, char *flags)
{
while (*buf != '\0') {
if (*buf == '-') {
buf++;
while (!isspace(*buf) && *buf != '\0')
*flags++ = *buf++;
}
buf++;
}
*flags = '\0';
return flags;
}
11 changes: 11 additions & 0 deletions arg_parse.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef ARG_PARSE_H
#define ARG_PARSE_H

#include "misc.h"

int get_argc(char *s);
char *skip_flag(char *s);
char **get_args(char *s, int index);
char *get_flags(char *buf, char *flags);

#endif
200 changes: 200 additions & 0 deletions cli.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
#include <dirent.h>
#include <getopt.h>
#include "misc.h"
#include "cmd_mains.h"

int rm(const char *name, int vflag, int pflag, int rflag)
{
if (pflag && !prompt("rm: remove \'%s\'? [y/n] ", name))
return 0;

if (is_dir(name) && rflag) {
removedir(name, 1);
return 0;
}
if (unlink(name) == -1) {
error("can't delete file %s.", name);
}
if (vflag)
printf("removed '%s'\n", name);

return 0;
}

int ls(const char *name, int aflag, int iflag, int rflag)
{
DIR *dp;
struct dirent *ep;
static int count = 0, index = 1;
/* TODO: modify ouput to correctly align
* contents when i and r flags are set */
dp = opendir(name);
if (dp != NULL) {
while ((ep = readdir(dp)) != NULL) {
if (!aflag && ep->d_name[0] == '.')
continue;
if (ep->d_type == 4 && rflag)
ls(ep->d_name, aflag, iflag, rflag);
(iflag) ? printf("%2d: %s", index++, ep->d_name) : printf("%10s", ep->d_name);
if (count == 4) {
putchar('\n');
count = 0;
} else {
putchar('\t');
count++;
}
}
putchar('\n');
} else {
error("can't open directory %s.", name);
}
if (closedir(dp) == -1)
error("can't close directory %s.", name);

return 0;
}

int clear(void)
{
int i;

for (i = 0; i < SCREEN_HEIGHT; ++i)
putchar('\n');
return 0;
}

int makedir(const char *name, int vflag)
{
/* create dir with read/write priveleges */
if (mkdir(name, S_IRWXU) == -1)
error("can't make directory %s.", name);
if (vflag)
printf("created directory '%s'\n", name);

return 0;
}

int cat(const char *name, int nflag)
{
int c;
int count = 1;
FILE *fp;

if (is_dir(name)) {
fprintf(stderr, "error: '%s' is a directory\n", name);
return 1;
}
fp = fopen(name, "r");
if (fp == NULL)
error("can't open file %s.", name);

if (nflag)
printf("\t%d: ", count++);

/* unbuffered input is used because it makes it easier to detect
* newlines when the n flag is set. */
while ((c = getc(fp)) != EOF) {
putchar(c);
if (c == '\n' && nflag)
printf("\t%d: ", count++);
}
if (c != '\n')
putchar('\n');

return 0;
}

int pwd(void)
{
char buf[BUFSIZE];

getcwd(buf, BUFSIZE);
if (buf == NULL)
error("can't get cwd.");
puts(buf);

return 0;
}

int cd(const char *path)
{
if (chdir(path) == -1)
error("can't change to directory %s.", path);
return 0;
}

int removedir(const char *name, int rflag)
{
DIR *dp;
struct dirent *ep;
char cwd[NAME_MAX];

if (rflag) {
getcwd(cwd, NAME_MAX);
dp = opendir(name);
if (dp != NULL) {
cd(name);
while ((ep = readdir(dp)) != NULL) {
/* deleting the '.' or ".." directory does not
* work so they are skipped. Also. they don't
* have to be deleted for rmdir() to work */
if (strcmp(ep->d_name, ".") == 0 ||
strcmp(ep->d_name, "..") == 0)
continue;
if (is_dir(ep->d_name))
removedir(ep->d_name, 1);
else
rm(ep->d_name, 0, 0, 0);
}
} else
error("can't open directory %s.", name);
if (closedir(dp) == -1)
error("can't close directory %s.", name);

if (chdir(cwd) != -1) {
if (rmdir(name) == -1)
error("can't delete directory %s.", name);
} else
error("can't change to directory %s.", cwd);
} else {
if (rmdir(name) == -1)
error("can't delete directory %s.", name);
}

return 0;
}

int main(void)
{
char cwd[BUFSIZE], buf[BUFSIZE];

do {
getcwd(cwd, BUFSIZE);
printf("cli:%s%% ", (cwd == NULL) ? "" : cwd);

gets(buf);
if (strlen(buf) == 0)
continue;
if (strncmp(buf, "rm", 2) == 0 && !isalnum(buf[2]))
rm_main(buf);
else if (strncmp(buf, "ls ", 2) == 0 && !isalnum(buf[2]))
ls_main(buf);
else if (strncmp(buf, "clear", 5) == 0 && !isalnum(buf[5]))
clear();
else if (strncmp(buf, "mkdir", 5) == 0 && !isalnum(buf[5]))
mkdir_main(buf);
else if (strncmp(buf, "cat", 3) == 0 && !isalnum(buf[3]))
cat_main(buf);
else if (strncmp(buf, "pwd", 3) == 0 && !isalnum(buf[3]))
pwd();
else if (strncmp(buf, "cd", 2) == 0 && !isalnum(buf[2]))
cd_main(buf);
else if (strncmp(buf, "help", 4) == 0 && !isalnum(buf[4]))
usage();
else
printf("cli: not a valid command.\n"
"type 'help' for a list of options\n\n");
} while (strcmp(buf, "exit") != 0);

return 0;
}
78 changes: 78 additions & 0 deletions misc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "misc.h"

void error(char *fmt, ...)
{
va_list args;

va_start(args, fmt);
fprintf(stderr, "error: ");
vfprintf(stderr, fmt, args);
fprintf(stderr, " ");
perror(NULL);
va_end(args);
exit(1);
}

bool prompt(char *fmt, ...)
{
char c;
va_list args;

va_start(args, fmt);
vfprintf(stdout, fmt, args);
va_end(args);

c = getchar();
if (c == 'y')
return true;
else
return false;
}

void usage(void)
{
printf("cli usage: COMMAND [FLAGS] ([FILE(s)])\n\n"
"rm\tdelete a file.\n"
"ls\tlist directory contents.\n"
"mkdir\tcreat a directory.\n"
"cat\tprint contents of a file.\n"
"cd\tchange working directory.\n\n"
"appending \" -h\" to most commands will give\n"
"additional info regarding that command\n\n");
exit(0);
}

char *strdup(const char *s)
{
char *d = malloc(strlen(s) + 1);
if (d == NULL)
return NULL;
strcpy(d, s);
return d;
}

int is_dir(const char *file)
{
struct stat statbuf;

stat(file, &statbuf);
return S_ISDIR(statbuf.st_mode);
}

int create_file(const char *name)
{
int fd;
if ((fd = creat(name, S_IRWXU)) == -1)
error("can't create file %s.", name);
return fd;
}

int open_file(const char *name, int flag)
{
int fd;

fd = open(name, flag);
if (fd == -1)
error("can't open file %s.", name);
return fd;
}
Loading

0 comments on commit 80779d1

Please sign in to comment.