Going on
This commit is contained in:
parent
65c7504898
commit
4f7dc3b92e
150
src/ls.c
150
src/ls.c
|
@ -5,13 +5,13 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
extern int optind;
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
/* FIXME */
|
||||
|
@ -20,24 +20,26 @@ extern int optind;
|
|||
/* Prefs */
|
||||
typedef int Prefs;
|
||||
#define PREFS_a 1
|
||||
#define PREFS_d 2
|
||||
#define PREFS_l 4
|
||||
#define PREFS_1 8
|
||||
#define PREFS_R 16
|
||||
#define PREFS_c 2
|
||||
#define PREFS_d 4
|
||||
#define PREFS_l 8
|
||||
#define PREFS_u 16
|
||||
#define PREFS_1 32
|
||||
#define PREFS_R 64
|
||||
|
||||
static int _prefs_parse(Prefs * prefs, int argc, char * argv[])
|
||||
{
|
||||
int o;
|
||||
|
||||
memset(prefs, 0, sizeof(Prefs));
|
||||
while((o = getopt(argc, argv, "CFRadl1")) != -1)
|
||||
while((o = getopt(argc, argv, "CFRacdlu1")) != -1)
|
||||
{
|
||||
switch(o)
|
||||
{
|
||||
case 'C':
|
||||
case 'F':
|
||||
fprintf(stderr, "%s%c%s", "ls: -", o,
|
||||
": Not yet implemented\n");
|
||||
": Not implemented yet\n");
|
||||
return 1;
|
||||
case 'R':
|
||||
*prefs |= PREFS_R;
|
||||
|
@ -45,12 +47,20 @@ static int _prefs_parse(Prefs * prefs, int argc, char * argv[])
|
|||
case 'a':
|
||||
*prefs |= PREFS_a;
|
||||
break;
|
||||
case 'c':
|
||||
*prefs -= *prefs & PREFS_u;
|
||||
*prefs |= PREFS_c;
|
||||
break;
|
||||
case 'd':
|
||||
*prefs |= PREFS_d;
|
||||
break;
|
||||
case 'l':
|
||||
*prefs |= PREFS_l;
|
||||
break;
|
||||
case 'u':
|
||||
*prefs -= *prefs & PREFS_c;
|
||||
*prefs |= PREFS_u;
|
||||
break;
|
||||
case '1':
|
||||
*prefs |= PREFS_1;
|
||||
break;
|
||||
|
@ -125,15 +135,15 @@ static void slist_next(SList * slist)
|
|||
*slist = (*slist)->next;
|
||||
}
|
||||
|
||||
static void slist_last(SList * slist)
|
||||
/* static void slist_last(SList * slist)
|
||||
{
|
||||
if(*slist == NULL)
|
||||
return;
|
||||
while((*slist)->next != NULL)
|
||||
*slist = (*slist)->next;
|
||||
}
|
||||
} */
|
||||
|
||||
static int slist_append(SList * slist, void * data)
|
||||
/* static int slist_append(SList * slist, void * data)
|
||||
{
|
||||
SList sl = *slist;
|
||||
|
||||
|
@ -145,7 +155,7 @@ static int slist_append(SList * slist, void * data)
|
|||
slist_last(&sl);
|
||||
sl->next = _slistcell_new(data, NULL);
|
||||
return sl->next != NULL ? 0 : 2;
|
||||
}
|
||||
} */
|
||||
|
||||
static void slist_apply(SList * slist, int (*func)(void *, void *), void * user)
|
||||
{
|
||||
|
@ -183,7 +193,7 @@ static int slist_insert_sorted(SList * slist, void * data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static size_t slist_length(SList * slist)
|
||||
/* static size_t slist_length(SList * slist)
|
||||
{
|
||||
SListCell * slc = *slist;
|
||||
size_t len;
|
||||
|
@ -191,7 +201,7 @@ static size_t slist_length(SList * slist)
|
|||
for(len = 0; slc != NULL; len++)
|
||||
slc = slc->next;
|
||||
return len;
|
||||
}
|
||||
} */
|
||||
|
||||
|
||||
/* ls */
|
||||
|
@ -200,6 +210,7 @@ static int _ls_directory_do(char * dir, Prefs * prefs);
|
|||
static int _ls_args(SList ** files, SList ** dirs);
|
||||
static int _is_directory(char * dir, Prefs * prefs);
|
||||
static int _ls_do(char * directory, SList * files, SList * dirs, Prefs * prefs);
|
||||
typedef int (*compare_func)(void*, void*);
|
||||
static int _ls(int argc, char * argv[], Prefs * prefs)
|
||||
{
|
||||
SList * files;
|
||||
|
@ -227,10 +238,12 @@ static int _ls(int argc, char * argv[], Prefs * prefs)
|
|||
}
|
||||
if(*prefs & PREFS_d)
|
||||
{
|
||||
res += slist_insert_sorted(files, str, strcmp);
|
||||
res += slist_insert_sorted(files, str,
|
||||
(compare_func)strcmp);
|
||||
continue;
|
||||
}
|
||||
res += slist_insert_sorted(j ? dirs : files, str, strcmp);
|
||||
res += slist_insert_sorted(j ? dirs : files, str,
|
||||
(compare_func)strcmp);
|
||||
}
|
||||
res += _ls_do(NULL, files, dirs, prefs);
|
||||
return res == 1 ? 2 : res;
|
||||
|
@ -252,6 +265,7 @@ static int _ls_directory_do(char * directory, Prefs * prefs)
|
|||
struct dirent * de;
|
||||
char * file = NULL;
|
||||
char * p;
|
||||
int pos = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "_ls_directory_do(%s, ...)\n", directory);
|
||||
|
@ -259,11 +273,15 @@ static int _ls_directory_do(char * directory, Prefs * prefs)
|
|||
if((dir = opendir(directory)) == NULL)
|
||||
return _ls_error(directory, 2);
|
||||
_ls_args(&files, &dirs);
|
||||
readdir(dir);
|
||||
readdir(dir);
|
||||
while((de = readdir(dir)) != NULL)
|
||||
{
|
||||
slist_insert_sorted(files, strdup(de->d_name), strcmp);
|
||||
pos++;
|
||||
if(*(de->d_name) == '.' && !(*prefs & PREFS_a))
|
||||
continue;
|
||||
slist_insert_sorted(files, strdup(de->d_name),
|
||||
(compare_func)strcmp);
|
||||
if(pos <= 2)
|
||||
continue;
|
||||
if((p = realloc(file, strlen(directory)
|
||||
+ strlen(de->d_name)
|
||||
+ 2)) == NULL)
|
||||
|
@ -274,7 +292,8 @@ static int _ls_directory_do(char * directory, Prefs * prefs)
|
|||
file = p;
|
||||
sprintf(file, "%s/%s", directory, de->d_name);
|
||||
if((*prefs & PREFS_R) && _is_directory(file, prefs) == 1)
|
||||
slist_insert_sorted(dirs, strdup(file), strcmp);
|
||||
slist_insert_sorted(dirs, strdup(file),
|
||||
(compare_func)strcmp);
|
||||
}
|
||||
free(file);
|
||||
closedir(dir);
|
||||
|
@ -304,13 +323,13 @@ static int _is_directory(char * file, Prefs * prefs)
|
|||
}
|
||||
|
||||
static int _ls_do_files(char * directory, SList * files, Prefs * prefs);
|
||||
static int _ls_do_dirs(char * directory, SList * dirs, Prefs * prefs);
|
||||
static int _ls_do_dirs(SList * dirs, Prefs * prefs);
|
||||
static int _ls_do(char * directory, SList * files, SList * dirs, Prefs * prefs)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
res += _ls_do_files(directory, files, prefs);
|
||||
res += _ls_do_dirs(directory, dirs, prefs);
|
||||
res += _ls_do_dirs(dirs, prefs);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -373,7 +392,7 @@ static int _ls_do_files_short(SList * files, Prefs * prefs)
|
|||
static void _long_mode(char str[11], mode_t mode);
|
||||
static char * _long_owner(uid_t uid);
|
||||
static char * _long_group(gid_t gid);
|
||||
static char * _long_date(time_t date);
|
||||
static void _long_date(time_t date, char buf[15]);
|
||||
static int _ls_do_files_long(char * directory, SList * files, Prefs * prefs)
|
||||
{
|
||||
SList cur;
|
||||
|
@ -383,7 +402,7 @@ static int _ls_do_files_long(char * directory, SList * files, Prefs * prefs)
|
|||
char mode[11];
|
||||
char * owner;
|
||||
char * group;
|
||||
char * date;
|
||||
char date[15];
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG _ls_do_files_long(%s, ...)\n", directory);
|
||||
|
@ -391,15 +410,16 @@ static int _ls_do_files_long(char * directory, SList * files, Prefs * prefs)
|
|||
for(cur = *files; cur != NULL; slist_next(&cur))
|
||||
{
|
||||
/* FIXME */
|
||||
if((p = realloc(file, strlen(directory)
|
||||
+ strlen(slist_data(&cur))
|
||||
+ 2)) == NULL)
|
||||
p = slist_data(&cur);
|
||||
if((p = realloc(file, strlen(directory) + strlen(p) + 2))
|
||||
== NULL)
|
||||
{
|
||||
_ls_error("malloc", 0);
|
||||
continue;
|
||||
}
|
||||
file = p;
|
||||
sprintf(file, "%s/%s", directory, slist_data(&cur));
|
||||
p = slist_data(&cur);
|
||||
sprintf(file, "%s/%s", directory, p);
|
||||
if(stat(file, &st) != 0)
|
||||
{
|
||||
_ls_error(file, 0);
|
||||
|
@ -408,10 +428,14 @@ static int _ls_do_files_long(char * directory, SList * files, Prefs * prefs)
|
|||
_long_mode(mode, st.st_mode);
|
||||
owner = _long_owner(st.st_uid);
|
||||
group = _long_group(st.st_gid);
|
||||
date = _long_date(st.st_mtime);
|
||||
if(*prefs & PREFS_u)
|
||||
_long_date(st.st_atime, date);
|
||||
else if(*prefs & PREFS_c)
|
||||
_long_date(st.st_ctime, date);
|
||||
else
|
||||
_long_date(st.st_mtime, date);
|
||||
printf("%s %u %s %s %lu %s %s\n", mode, st.st_nlink,
|
||||
owner, group, st.st_size, date,
|
||||
slist_data(&cur));
|
||||
owner, group, st.st_size, date, p);
|
||||
}
|
||||
free(file);
|
||||
return 0;
|
||||
|
@ -421,10 +445,43 @@ static void _long_mode(char str[11], mode_t mode)
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
str[10] = '\0';
|
||||
/* FIXME */
|
||||
for(i = 0; i < 10; i++)
|
||||
str[0] = '-';
|
||||
if(!S_ISREG(mode))
|
||||
{
|
||||
if(S_ISLNK(mode))
|
||||
str[0] = 'l';
|
||||
else if(S_ISBLK(mode))
|
||||
str[0] = 'b';
|
||||
else if(S_ISCHR(mode))
|
||||
str[0] = 'c';
|
||||
else if(S_ISFIFO(mode))
|
||||
str[0] = 'p';
|
||||
else if(S_ISDIR(mode))
|
||||
str[0] = 'd';
|
||||
}
|
||||
for(i = 1; i < 10; i++)
|
||||
str[i] = '-';
|
||||
if(mode & S_IRUSR)
|
||||
str[1] = 'r';
|
||||
if(mode & S_IWUSR)
|
||||
str[2] = 'w';
|
||||
if(mode & S_IXUSR)
|
||||
str[3] = (mode & S_ISUID ? 's' : 'x');
|
||||
else if(mode & S_ISUID)
|
||||
str[3] = 'S';
|
||||
if(mode & S_IRGRP)
|
||||
str[4] = 'r';
|
||||
if(mode & S_IWGRP)
|
||||
str[5] = 'w';
|
||||
if(mode & S_IXGRP)
|
||||
str[6] = 'x';
|
||||
if(mode & S_IROTH)
|
||||
str[7] = 'r';
|
||||
if(mode & S_IWOTH)
|
||||
str[8] = 'w';
|
||||
if(mode & S_IXOTH)
|
||||
str[9] = 'x';
|
||||
str[10] = '\0';
|
||||
}
|
||||
|
||||
static char * _long_owner(uid_t uid)
|
||||
|
@ -445,10 +502,18 @@ static char * _long_group(gid_t gid)
|
|||
return grp->gr_name;
|
||||
}
|
||||
|
||||
static char * _long_date(time_t date)
|
||||
static void _long_date(time_t date, char buf[15])
|
||||
{
|
||||
/* FIXME */
|
||||
return NULL;
|
||||
struct tm tm;
|
||||
static time_t sixmonths = -1;
|
||||
|
||||
if(sixmonths == -1)
|
||||
sixmonths = time(NULL) - 15552000;
|
||||
localtime_r(&date, &tm);
|
||||
if(date < sixmonths)
|
||||
strftime(buf, 14, "%b %e %Y", &tm);
|
||||
else
|
||||
strftime(buf, 14, "%b %e %H:%M", &tm);
|
||||
}
|
||||
|
||||
static int _ls_free(void * data, void * user)
|
||||
|
@ -458,16 +523,12 @@ static int _ls_free(void * data, void * user)
|
|||
user = user;
|
||||
}
|
||||
|
||||
static int _ls_do_dirs(char * directory, SList * dirs, Prefs * prefs)
|
||||
static int _ls_do_dirs(SList * dirs, Prefs * prefs)
|
||||
{
|
||||
int res = 0;
|
||||
SList cur;
|
||||
char * dir = NULL;
|
||||
char * p;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG _ls_do_dirs(%s, ...)\n", directory);
|
||||
#endif
|
||||
for(cur = *dirs; cur != NULL; slist_next(&cur))
|
||||
{
|
||||
dir = slist_data(&cur);
|
||||
|
@ -483,7 +544,12 @@ static int _ls_do_dirs(char * directory, SList * dirs, Prefs * prefs)
|
|||
/* usage */
|
||||
static int _usage(void)
|
||||
{
|
||||
fprintf(stderr, "%s", "Usage: ls [-CFRadl1]\n");
|
||||
fprintf(stderr, "%s", "Usage: ls [-CFRacdilqrtu1][-H | -L]\n\
|
||||
-R recursively list subdirectories encountered\n\
|
||||
-a write out all hidden directory entries\n\
|
||||
-c use time of last modification of file status\n\
|
||||
-l write out in long format\n\
|
||||
-u use time of last access\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
50
src/uniq.c
50
src/uniq.c
|
@ -19,9 +19,10 @@
|
|||
* 0 success
|
||||
* else error(s) occured */
|
||||
static int _uniq_error(char * message, int ret);
|
||||
static int _uniq_do(int opts, char * fields, int chars,
|
||||
static int _uniq_do(int opts, char * fields, unsigned int skip,
|
||||
FILE * infp, FILE * outfp);
|
||||
static int _uniq(int opts, char * fields, int chars, char * in, char * out)
|
||||
static int _uniq(int opts, char * fields, unsigned int skip,
|
||||
char * in, char * out)
|
||||
{
|
||||
FILE * infp = stdin;
|
||||
FILE * outfp = stdout;
|
||||
|
@ -34,7 +35,7 @@ static int _uniq(int opts, char * fields, int chars, char * in, char * out)
|
|||
fclose(infp);
|
||||
return _uniq_error(out, 2);
|
||||
}
|
||||
ret = _uniq_do(opts, fields, chars, infp, outfp);
|
||||
ret = _uniq_do(opts, fields, skip, infp, outfp);
|
||||
if(in == NULL)
|
||||
{
|
||||
fclose(infp);
|
||||
|
@ -51,8 +52,8 @@ static int _uniq_error(char * message, int ret)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void _do_count(int opts, char * line, FILE * fp);
|
||||
static int _uniq_do(int opts, char * fields, int chars,
|
||||
static void _do_count(int opts, unsigned int skip, char * line, FILE * fp);
|
||||
static int _uniq_do(int opts, char * fields, unsigned int skip,
|
||||
FILE * infp, FILE * outfp)
|
||||
{
|
||||
#define BUF 80
|
||||
|
@ -84,15 +85,16 @@ static int _uniq_do(int opts, char * fields, int chars,
|
|||
#ifdef DEBUG
|
||||
fprintf(stderr, "%s%s%s", "DEBUG: Got line \"", line, "\"\n");
|
||||
#endif
|
||||
_do_count(opts, line, outfp);
|
||||
_do_count(opts, skip, line, outfp);
|
||||
line = NULL;
|
||||
len = 0;
|
||||
}
|
||||
_do_count(opts, NULL, outfp);
|
||||
_do_count(opts, skip, NULL, outfp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _do_count(int opts, char * line, FILE * fp)
|
||||
static int _count_repeated(char * lastline, char * line, unsigned int skip);
|
||||
static void _do_count(int opts, unsigned int skip, char * line, FILE * fp)
|
||||
{
|
||||
static char * lastline = NULL;
|
||||
static unsigned int cnt = 1;
|
||||
|
@ -102,7 +104,7 @@ static void _do_count(int opts, char * line, FILE * fp)
|
|||
lastline = line;
|
||||
return;
|
||||
}
|
||||
if(line != NULL && strcmp(lastline, line) == 0)
|
||||
if(line != NULL && _count_repeated(lastline, line, skip))
|
||||
{
|
||||
cnt++;
|
||||
return;
|
||||
|
@ -120,12 +122,29 @@ static void _do_count(int opts, char * line, FILE * fp)
|
|||
cnt = 1;
|
||||
}
|
||||
|
||||
/* PRE line and lastline are valid strings
|
||||
* POST */
|
||||
static int _count_repeated(char * lastline, char * line, unsigned int skip)
|
||||
{
|
||||
if(strlen(lastline) < skip)
|
||||
return strlen(line) < skip;
|
||||
if(strlen(line) < skip)
|
||||
return 0;
|
||||
if(strcmp(&lastline[skip], &line[skip]) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* usage */
|
||||
static int _usage(void)
|
||||
{
|
||||
fprintf(stderr, "%s", "Usage: uniq [-c|-d|-u][-f fields][-s char]\
|
||||
[input_file [output_file]]\n");
|
||||
[input_file [output_file]]\n\
|
||||
-c precede each output line with a count of the repetitions for the line\n\
|
||||
-d suppress the writing of lines that are not repeated\n\
|
||||
-s ignore the first char characters when doing comparisons\n\
|
||||
-u suppress the writing of lines that are repeated\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -133,7 +152,8 @@ int main(int argc, char * argv[])
|
|||
{
|
||||
int opts = 0;
|
||||
char * fields = NULL;
|
||||
int chars = 0;
|
||||
int skip = 0;
|
||||
char * p;
|
||||
char * in = NULL;
|
||||
char * out = NULL;
|
||||
int o;
|
||||
|
@ -148,11 +168,15 @@ int main(int argc, char * argv[])
|
|||
case 'd':
|
||||
opts |= OPTS_d;
|
||||
break;
|
||||
case 's':
|
||||
skip = strtol(optarg, &p, 10);
|
||||
if(*optarg == '\0' || *p != '\0' || skip < 0)
|
||||
return _usage();
|
||||
break;
|
||||
case 'u':
|
||||
opts |= OPTS_u;
|
||||
break;
|
||||
case 'f':
|
||||
case 's':
|
||||
fprintf(stderr, "%s%c%s", "uniq: -", o,
|
||||
": Not implemented yet\n");
|
||||
return _usage();
|
||||
|
@ -168,5 +192,5 @@ int main(int argc, char * argv[])
|
|||
else if(argc - optind > 2)
|
||||
return _usage();
|
||||
}
|
||||
return _uniq(opts, fields, chars, in, out);
|
||||
return _uniq(opts, fields, skip, in, out);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user