first commit
This commit is contained in:
commit
21be7fd279
14
LICENSE
Normal file
14
LICENSE
Normal file
@ -0,0 +1,14 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
5
README.md
Normal file
5
README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# micro-utils
|
||||
Own implementation of *nix utils
|
||||
License: wtfpl
|
||||
|
||||
Author: 8nl
|
57
TODO
Normal file
57
TODO
Normal file
@ -0,0 +1,57 @@
|
||||
With "micro-" prefix
|
||||
|
||||
*Todo:
|
||||
tail
|
||||
expr
|
||||
uniq
|
||||
od
|
||||
tr
|
||||
cut
|
||||
shuf
|
||||
stty
|
||||
sort
|
||||
test
|
||||
tar
|
||||
sha*
|
||||
md5
|
||||
|
||||
Other:
|
||||
watch
|
||||
ps
|
||||
sysctl
|
||||
ping
|
||||
ncat
|
||||
ntpd
|
||||
ifconfig
|
||||
dhcp-client
|
||||
getopt
|
||||
fdisk
|
||||
less
|
||||
free
|
||||
swapon
|
||||
swapoff
|
||||
hexdump
|
||||
|
||||
Loginutils:
|
||||
userctl
|
||||
groupctl
|
||||
getty
|
||||
|
||||
Modutils:
|
||||
insmod
|
||||
rmmod
|
||||
lsmod
|
||||
|
||||
Findutils:
|
||||
grep
|
||||
find
|
||||
|
||||
BUGS:
|
||||
ls (-l flag with long group/user name)
|
||||
xargs (getopt with glibc)
|
||||
|
||||
FIX:
|
||||
ps
|
||||
head
|
||||
echo (escape)
|
||||
que (unicode)
|
0
bin/.gitignore
vendored
Executable file
0
bin/.gitignore
vendored
Executable file
36
build.sh
Executable file
36
build.sh
Executable file
@ -0,0 +1,36 @@
|
||||
#!/bin/sh
|
||||
if [ -z $PROJECT_DIR ]; then
|
||||
PROJECT_DIR=$(pwd)
|
||||
fi
|
||||
|
||||
if [ -z $CFLAGS ]; then
|
||||
CFLAGS="-pedantic -s -Os -Wall -Wextra -D_GNU_SOURCE -D_DEFAULT_SOURCE -D_BSD_SOURCE"
|
||||
fi
|
||||
|
||||
if [ -z $CC ]; then
|
||||
CC=cc
|
||||
fi
|
||||
|
||||
if [ -z $projects ]; then
|
||||
projects="editors sysutils-linux init console-tools coreutils findutils networking loginutils procps"
|
||||
fi
|
||||
|
||||
#Compile
|
||||
for project in $projects; do
|
||||
echo "Chdir" $project
|
||||
|
||||
for p in src/$project/*; do
|
||||
echo " * Makeing" $p
|
||||
|
||||
for i in $p; do
|
||||
cd $PROJECT_DIR/$i
|
||||
echo " * Compile" $i
|
||||
chmod -v +x build.sh
|
||||
env CC=$CC CFLAGS="$CFLAGS -I$PROJECT_DIR -I$PROJECT_DIR/include/libmu" OUTPUT="$PROJECT_DIR"/bin/ ./build.sh
|
||||
cd $PROJECT_DIR
|
||||
done
|
||||
echo -ne "\n"
|
||||
done
|
||||
done
|
||||
|
||||
chmod -vR a+x bin/
|
60
config.h
Normal file
60
config.h
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
|
||||
/* (cat tee wc xargs rev split cp) text buffer */
|
||||
#define BUF_SIZE 1024 * 1024
|
||||
|
||||
#ifdef _SHRED_C
|
||||
/* Random source (shred) */
|
||||
#define RAND_SOURCE "/dev/urandom"
|
||||
#endif
|
||||
|
||||
#ifdef _HEAD_C
|
||||
/* format for printf (head) */
|
||||
#define HEAD_FMT "==> %s <==\n"
|
||||
#endif
|
||||
|
||||
#ifdef _PW_CHECK_H
|
||||
/* Pw_check. Salt for crypt() */
|
||||
char MU_SALT_ENC[] = {'s', 'a', 'l', 't'};
|
||||
char MU_SALT_BUF[sizeof(MU_SALT_ENC) + 1];
|
||||
#endif
|
||||
|
||||
#ifdef _MOUNT_C
|
||||
/* mount config */
|
||||
#define MOUNT_CFG "/etc/fstab"
|
||||
#define MOUNT_DEF_FS "ext4"
|
||||
#define MOUNT_LIST "/proc/mounts"
|
||||
#define MOUNT_OPT_SIZE 512
|
||||
#endif
|
||||
|
||||
#ifdef _LS_C
|
||||
/* colors for ls */
|
||||
#define LS_DIR_COLOR "\033[1;34m"
|
||||
#define LS_LINK_COLOR "\033[1;35m"
|
||||
#define LS_SOCK_COLOR "\033[35m"
|
||||
#define LS_FIFO_COLOR "\033[1;35m"
|
||||
#define LS_BLOCK_COLOR "\033[1;33m"
|
||||
#define LS_EXE_COLOR "\033[1;32m"
|
||||
#endif
|
||||
|
||||
#ifdef INIT
|
||||
/* Init scripts */
|
||||
char *INIT_POWEROFF[] = {"/etc/rc.poweroff", NULL};
|
||||
char *INIT_START[] = {"/etc/rc.init", NULL};
|
||||
#define INIT_MSG "Starting micro-init..."
|
||||
#endif
|
||||
|
||||
#ifdef _UNAME_C
|
||||
/* Os name for uname */
|
||||
/* #define OS_NAME "unknow" */
|
||||
#endif
|
||||
|
||||
/* Options: To disable, comment line */
|
||||
|
||||
/* getloadavg() unavailable in android */
|
||||
#ifndef __ANDROID__
|
||||
#define UPTIME_LOADAVG
|
||||
#endif
|
||||
|
||||
#endif
|
9
configs/fstab
Normal file
9
configs/fstab
Normal file
@ -0,0 +1,9 @@
|
||||
#Example
|
||||
#[SRC] [DST] [FS TYPE] [OPTIONS. Default: default] [Unused] [Unused]
|
||||
#/dev/sda1 /boot ext4 rw 0 0
|
||||
#/dev/disk/by-uuid/disk-uuid-12dfg /usr f2fs 0 0
|
||||
|
||||
proc /proc proc nosuid,noexec,nodev 0 0
|
||||
sysfs /sys sysfs nosuid,noexec,nodev 0 0
|
||||
devtmpfs /dev devtmpfs gid=5,mode=0620 0 0
|
||||
tmpfs /tmp tmpfs nosuid,noexec,nodev,mode=0777 0 0
|
2
configs/group
Normal file
2
configs/group
Normal file
@ -0,0 +1,2 @@
|
||||
root::0:root
|
||||
|
1
configs/hostname
Normal file
1
configs/hostname
Normal file
@ -0,0 +1 @@
|
||||
localhost
|
1
configs/motd
Normal file
1
configs/motd
Normal file
@ -0,0 +1 @@
|
||||
Welcome!
|
4
configs/os-release
Normal file
4
configs/os-release
Normal file
@ -0,0 +1,4 @@
|
||||
NAME="Plain Os"
|
||||
ID=plainos
|
||||
VERSION_ID=0.1
|
||||
PRETTY_NAME="PlainOs/Linux 0.1 "
|
2
configs/passwd
Normal file
2
configs/passwd
Normal file
@ -0,0 +1,2 @@
|
||||
root::0:0:root:/usr/root:/bin/sh
|
||||
nobody:*:65534:65534:nobody:/nonexistent:/bin/false
|
9
configs/rc.init
Normal file
9
configs/rc.init
Normal file
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
echo "[*] Mounting..."
|
||||
mount -a
|
||||
|
||||
echo "[*] Hostname..."
|
||||
hostname -c /etc/hostname
|
||||
|
||||
cat /etc/motd
|
||||
env TERM="linux" login
|
12
configs/rc.poweroff
Normal file
12
configs/rc.poweroff
Normal file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
echo "[*] Umounting..."
|
||||
umount -a
|
||||
|
||||
echo "[*] Syncing..."
|
||||
sync
|
||||
|
||||
echo "[*] Closing processes..."
|
||||
kill -a -s TERM
|
||||
sleep 5
|
||||
|
||||
echo "[*] Poweroff..."
|
1
configs/resolv.conf
Normal file
1
configs/resolv.conf
Normal file
@ -0,0 +1 @@
|
||||
nameserver 192.168.0.1
|
48
include/libmu/duration.h
Normal file
48
include/libmu/duration.h
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef _DURATION_H
|
||||
#define _DURATION_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
unsigned long long parse_uint(const char *str) {
|
||||
char *p = NULL;
|
||||
|
||||
unsigned long long res = strtoull(str, &p, 0);
|
||||
|
||||
/* Parse suffix */
|
||||
if (*p) {
|
||||
switch (p[0]) {
|
||||
case 'm':
|
||||
res *= 60;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
res *= 3600;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
res *= 86400;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
unsigned long long mu_parse_duration(const char *arg) {
|
||||
if (strchr(arg, '.')) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
else {
|
||||
/* Sec */
|
||||
return parse_uint(arg) * 1000000;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
39
include/libmu/get_stat.h
Normal file
39
include/libmu/get_stat.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef _GET_STAT_H
|
||||
#define _GET_STAT_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int mu_get_stat(const char *prog_name, const char *path, struct stat *stat_path) {
|
||||
if (stat(path, stat_path)) {
|
||||
if (prog_name != NULL)
|
||||
fprintf(stderr, "%s: %s: %s\n", prog_name, path, strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mu_get_lstat(const char *prog_name, const char *path, struct stat *stat_path) {
|
||||
if (lstat(path, stat_path)) {
|
||||
if (prog_name != NULL)
|
||||
fprintf(stderr, "%s: %s: %s\n", prog_name, path, strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mu_get_stats(const char *prog_name, int flag, const char *path, struct stat *stat_path) {
|
||||
if (flag)
|
||||
return mu_get_lstat(prog_name, path, stat_path);
|
||||
|
||||
else
|
||||
return mu_get_stat(prog_name, path, stat_path);
|
||||
}
|
||||
|
||||
#endif
|
30
include/libmu/human.h
Normal file
30
include/libmu/human.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef _HUMAN_H
|
||||
#define _HUMAN_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MU_HUMAN_BUF_SIZE 16
|
||||
|
||||
char *mu_humansize(off_t n, off_t block) {
|
||||
static char mu_hs_buf[MU_HUMAN_BUF_SIZE + 1];
|
||||
memset(mu_hs_buf, '\0', sizeof(mu_hs_buf));
|
||||
|
||||
char *postfixes = "BKMGTPE";
|
||||
|
||||
double size = n;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < strlen(postfixes) && size >= block; i++)
|
||||
size /= block;
|
||||
|
||||
if (i)
|
||||
snprintf(mu_hs_buf, sizeof(mu_hs_buf), "%.1f%c", size, postfixes[i]);
|
||||
|
||||
else
|
||||
snprintf(mu_hs_buf, sizeof(mu_hs_buf), "%ju", n);
|
||||
|
||||
return mu_hs_buf;
|
||||
}
|
||||
|
||||
#endif
|
39
include/libmu/make_path.h
Normal file
39
include/libmu/make_path.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef _MAKE_PATH_H
|
||||
#define _MAKE_PATH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char *mu_make_path(const char *prog_name, const char *src, const char *dst) {
|
||||
int flag = 0;
|
||||
|
||||
if (src == NULL) {
|
||||
flag = 1;
|
||||
src = "";
|
||||
}
|
||||
|
||||
if (dst == NULL) {
|
||||
flag = 1;
|
||||
dst = "";
|
||||
}
|
||||
|
||||
size_t len = strlen(src) + strlen(dst) + 2;
|
||||
char *full_path = malloc(len + 1);
|
||||
if (full_path == NULL) {
|
||||
if (prog_name != NULL)
|
||||
fprintf(stderr, "%s: malloc() failed\n", prog_name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flag || src[strlen(src) - 1] == '/')
|
||||
snprintf(full_path, len, "%s%s", src, dst);
|
||||
|
||||
else
|
||||
snprintf(full_path, len, "%s/%s", src, dst);
|
||||
|
||||
return full_path;
|
||||
}
|
||||
|
||||
#endif
|
57
include/libmu/mode_to_str.h
Normal file
57
include/libmu/mode_to_str.h
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef _MODE_TO_STR_H
|
||||
#define _MODE_TO_STR_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
char *mu_mode_2_str(mode_t file_mode) {
|
||||
static char mode[11];
|
||||
snprintf(mode, sizeof(mode), "----------");
|
||||
|
||||
if (file_mode & S_IRUSR)
|
||||
mode[1] = 'r';
|
||||
|
||||
if (file_mode & S_IRGRP)
|
||||
mode[4] = 'r';
|
||||
|
||||
if (file_mode & S_IROTH)
|
||||
mode[7] = 'r';
|
||||
|
||||
if (file_mode & S_IWUSR)
|
||||
mode[2] = 'w';
|
||||
|
||||
if (file_mode & S_IWGRP)
|
||||
mode[5] = 'w';
|
||||
|
||||
if (file_mode & S_IWOTH)
|
||||
mode[8] = 'w';
|
||||
|
||||
if (file_mode & S_IXUSR)
|
||||
mode[3] = 'x';
|
||||
|
||||
if (file_mode & S_IXGRP)
|
||||
mode[6] = 'x';
|
||||
|
||||
if (file_mode & S_IXOTH)
|
||||
mode[9] = 'x';
|
||||
|
||||
if (file_mode & S_ISUID) {
|
||||
if (file_mode & S_IXUSR)
|
||||
mode[3] = 's';
|
||||
|
||||
else
|
||||
mode[3] = 'S';
|
||||
}
|
||||
|
||||
if (file_mode & S_ISGID) {
|
||||
if (file_mode & S_IRGRP)
|
||||
mode[6] = 's';
|
||||
|
||||
else
|
||||
mode[6] = 'S';
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
#endif
|
99
include/libmu/parse_mode.h
Normal file
99
include/libmu/parse_mode.h
Normal file
@ -0,0 +1,99 @@
|
||||
#ifndef _PARSE_MODE_H
|
||||
#define _PARSE_MODE_H
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
||||
#define U (S_ISUID | S_IRWXU)
|
||||
#define G (S_ISGID | S_IRWXG)
|
||||
#define O (S_IRWXO)
|
||||
#define A (U | G | O)
|
||||
|
||||
#define WR_PERM (S_IWUSR | S_IWGRP | S_IWOTH)
|
||||
#define EX_PERM (S_IXUSR | S_IXGRP | S_IXOTH)
|
||||
#define RD_PERM (S_IRUSR | S_IRGRP | S_IROTH)
|
||||
#define SU_PERM (S_ISUID | S_ISGID | S_ISVTX)
|
||||
#define FULL_PERM (WR_PERM | EX_PERM | RD_PERM)
|
||||
|
||||
mode_t mu_parse_mode(const char *s, mode_t cur_mode) {
|
||||
char *p = NULL;
|
||||
|
||||
mode_t mode = (mode_t)strtol(s, &p, 8);
|
||||
if (!*p && mode < 07777U)
|
||||
return mode;
|
||||
|
||||
else if (mode > 07777U)
|
||||
return 0;
|
||||
|
||||
mode = 0;
|
||||
|
||||
/* Default + */
|
||||
char append = 1;
|
||||
mode_t mask = 0;
|
||||
|
||||
for (size_t i = 0; i < strlen(s); i++) {
|
||||
switch (s[i]) {
|
||||
case 'r':
|
||||
mode |= RD_PERM;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
mode |= WR_PERM;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
mode |= EX_PERM;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
mode |= SU_PERM;
|
||||
break;
|
||||
|
||||
case '+':
|
||||
append = 1;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
append = 0;
|
||||
break;
|
||||
|
||||
case '=':
|
||||
append = 2;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
mask |= G;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
mask |= U;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
mask |= O;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
mask |= A;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask == 0)
|
||||
mask = U;
|
||||
|
||||
mask &= mode;
|
||||
if (append == 0)
|
||||
mode = ~mode;
|
||||
|
||||
if (append == 2)
|
||||
return mode & mask;
|
||||
|
||||
else
|
||||
return (cur_mode & ~mask) | (mode & mask);
|
||||
}
|
||||
|
||||
#endif
|
72
include/libmu/parse_mount.h
Normal file
72
include/libmu/parse_mount.h
Normal file
@ -0,0 +1,72 @@
|
||||
#ifndef _PARSE_MOUNT_H
|
||||
#define _PARSE_MOUNT_H
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
char *opt;
|
||||
char *notopt;
|
||||
char *desc;
|
||||
unsigned int val;
|
||||
} MU_MOUNT_OPTS;
|
||||
|
||||
MU_MOUNT_OPTS mu_options[] = {
|
||||
{"defaults", NULL, NULL, 0},
|
||||
{"ro", "rw", "Read only / Read and write", MS_RDONLY},
|
||||
{"remount", NULL, "Remount a mounted filesystem", MS_REMOUNT},
|
||||
{"sync", "async", "Writes are [a]synchronous", MS_SYNCHRONOUS},
|
||||
{"nodev", "dev", "(Dis)allow use of special device files", MS_NODEV},
|
||||
{"bind", "rbind", "Bind a file or directory", MS_BIND},
|
||||
{"noexec", "exec", "(Dis)allow use of executable files", MS_NOEXEC},
|
||||
{"noatime", "atime", "Disable/enable updates to inode access times", MS_NOATIME}
|
||||
};
|
||||
|
||||
unsigned long mu_parse_opts(char *str, char *data, const size_t data_size) {
|
||||
memset(data, '\0', data_size);
|
||||
unsigned long opt = 0;
|
||||
size_t data_len = 0;
|
||||
|
||||
char *token = strtok(str, ",");
|
||||
while (token != NULL) {
|
||||
int invalidopt = 1;
|
||||
for (size_t i = 0; i < sizeof(mu_options) / sizeof(mu_options[0]); i++) {
|
||||
if (mu_options[i].opt && !strcmp(token, mu_options[i].opt)) {
|
||||
opt |= mu_options[i].val;
|
||||
invalidopt = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mu_options[i].notopt && !strcmp(token, mu_options[i].notopt)) {
|
||||
opt &= ~mu_options[i].val;
|
||||
invalidopt = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unknow opt, pass in mount() */
|
||||
size_t len = strlen(token);
|
||||
if (invalidopt && len > 0) {
|
||||
/* Copy token string */
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (data_len + 1 >= data_size)
|
||||
break;
|
||||
|
||||
else {
|
||||
data[data_len] = token[i];
|
||||
data_len++;
|
||||
}
|
||||
}
|
||||
|
||||
if (data_len && data_len + 1 < data_size)
|
||||
data[data_len++] = ',';
|
||||
}
|
||||
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
if (data_len > 0)
|
||||
data[data_len - 1] = '\0';
|
||||
|
||||
return opt;
|
||||
}
|
||||
|
||||
#endif
|
59
include/libmu/pw_check.h
Normal file
59
include/libmu/pw_check.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef _PW_CHECK_H
|
||||
#define _PW_CHECK_H
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "config.h"
|
||||
|
||||
void dec_salt(void) {
|
||||
size_t i;
|
||||
for (i = 0; i < sizeof(MU_SALT_ENC) / sizeof(int); i++)
|
||||
MU_SALT_BUF[i] = MU_SALT_ENC[i];
|
||||
|
||||
MU_SALT_BUF[i + 1] = '\0';
|
||||
}
|
||||
|
||||
/* Using not only there */
|
||||
char *enc_password(const char *prog_name, const char *pass, const char *salt) {
|
||||
if (salt == NULL)
|
||||
dec_salt();
|
||||
|
||||
char *cpass = crypt(pass, (salt == NULL) ? MU_SALT_BUF : salt);
|
||||
if (cpass == NULL) {
|
||||
if (prog_name != NULL)
|
||||
fprintf(stderr, "%s: %s\n", prog_name, strerror(errno));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cpass;
|
||||
}
|
||||
|
||||
int pw_check(const char *prog_name, const struct passwd *pw, const char *pass) {
|
||||
if (pw->pw_passwd[0] == '\0' && pass[0] == '\0')
|
||||
return 0;
|
||||
|
||||
if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*') {
|
||||
if (prog_name != NULL)
|
||||
fprintf(stderr, "%s: Access denied\n", prog_name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *cpass = enc_password(prog_name, pass, NULL);
|
||||
if (cpass == NULL)
|
||||
return 1;
|
||||
|
||||
if (!strcmp(pw->pw_passwd, cpass))
|
||||
return 0;
|
||||
|
||||
if (prog_name != NULL)
|
||||
fprintf(stderr, "%s: Incorrect password\n", prog_name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
54
include/libmu/recurse.h
Normal file
54
include/libmu/recurse.h
Normal file
@ -0,0 +1,54 @@
|
||||
#ifndef _RECURSE_H
|
||||
#define _RECURSE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include "make_path.h"
|
||||
#include "get_stat.h"
|
||||
|
||||
int mu_recurse(const char *restrict prog_name, int link_flag, const char *restrict path, void *restrict arg, int (*file_act)(const char *path, void *p), int (*dir_act)(const char *path, void *p)) {
|
||||
|
||||
struct stat sb;
|
||||
if (mu_get_stats(prog_name, link_flag, path, &sb))
|
||||
return 1;
|
||||
|
||||
if (!S_ISDIR(sb.st_mode) || S_ISLNK(sb.st_mode)) {
|
||||
if (file_act != NULL)
|
||||
return file_act(path, arg);
|
||||
}
|
||||
|
||||
DIR *dir = opendir(path);
|
||||
if (dir == NULL) {
|
||||
if (prog_name != NULL)
|
||||
fprintf(stderr, "%s: %s: Can`t open directory\n", prog_name, path);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
|
||||
struct dirent *ep;
|
||||
while ((ep = readdir(dir)) != NULL) {
|
||||
if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, ".."))
|
||||
continue;
|
||||
|
||||
char *full_path = mu_make_path(prog_name, path, ep->d_name);
|
||||
if (full_path == NULL)
|
||||
continue;
|
||||
|
||||
if (mu_recurse(prog_name, link_flag, full_path, arg, file_act, dir_act))
|
||||
ret = 1;
|
||||
|
||||
free(full_path);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
if (dir_act != NULL)
|
||||
if (dir_act(path, arg))
|
||||
ret = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
6
include/libmu/unused.h
Normal file
6
include/libmu/unused.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef _UNUSED_H
|
||||
#define _UNUSED_H
|
||||
|
||||
#define UNUSED(p) ((void)p)
|
||||
|
||||
#endif
|
13
include/libmu/utf8_strlen.h
Normal file
13
include/libmu/utf8_strlen.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef _UTF8_STRLEN
|
||||
#define _UTF8_STRLEN
|
||||
|
||||
size_t utf8_strlen(const char *s) {
|
||||
size_t i = 0;
|
||||
|
||||
while (*s++)
|
||||
i += (*s & 0xC0) != 0x80;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
#endif
|
3
src/console-tools/clear/build.sh
Executable file
3
src/console-tools/clear/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
5
src/console-tools/clear/clear.c
Normal file
5
src/console-tools/clear/clear.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include <unistd.h>
|
||||
|
||||
int main(void) {
|
||||
return write(1, "\033[H\033[J", 6) != 6;
|
||||
}
|
3
src/console-tools/reset/build.sh
Executable file
3
src/console-tools/reset/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
5
src/console-tools/reset/reset.c
Normal file
5
src/console-tools/reset/reset.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include <unistd.h>
|
||||
|
||||
int main(void) {
|
||||
return write(1, "\033c\033(K\033[J\033[0m\033[?25h", 18) != 18;
|
||||
}
|
57
src/coreutils/bdname/bdname.c
Normal file
57
src/coreutils/bdname/bdname.c
Normal file
@ -0,0 +1,57 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
|
||||
char *bname(char *str, const char *suffix) {
|
||||
char *base = basename(str);
|
||||
|
||||
if (suffix) {
|
||||
char *ptr = base + strlen(base) - strlen(suffix);
|
||||
if (!strcmp(ptr, suffix))
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *suffix = NULL;
|
||||
char d_flag = 0;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "s:d")) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
d_flag = 1;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
suffix = optarg;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("bdname [sd] [str]\n\t-s SFX Set suffix\n\t-d Use dirname instead of basename\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc == 0) {
|
||||
fprintf(stderr, "bdname: missing operand\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *str = NULL;
|
||||
if (d_flag)
|
||||
str = dirname(argv[0]);
|
||||
|
||||
else
|
||||
str = bname(argv[0], suffix);
|
||||
|
||||
puts(str);
|
||||
return 0;
|
||||
}
|
3
src/coreutils/bdname/build.sh
Executable file
3
src/coreutils/bdname/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
3
src/coreutils/cat/build.sh
Executable file
3
src/coreutils/cat/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
54
src/coreutils/cat/cat.c
Normal file
54
src/coreutils/cat/cat.c
Normal file
@ -0,0 +1,54 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "config.h"
|
||||
|
||||
int cat(const char *path) {
|
||||
int fd = STDIN_FILENO;
|
||||
|
||||
if (strcmp(path, "-"))
|
||||
fd = open(path, O_RDONLY);
|
||||
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "cat: %s: %s\n", path, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
char buf[BUF_SIZE + 1];
|
||||
off_t len = 0;
|
||||
while ((len = read(fd, buf, sizeof(buf))) > 0)
|
||||
if (write(STDOUT_FILENO, buf, len) != len) {
|
||||
fprintf(stderr, "cat: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strcmp(path, "-"))
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "")) != -1) {
|
||||
printf("cat [file1 file2...]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc == 0)
|
||||
return cat("-");
|
||||
|
||||
else {
|
||||
int ret = 0;
|
||||
for (int i = 0; i < argc; i++)
|
||||
if (cat(argv[i]))
|
||||
ret = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
3
src/coreutils/chgrp/build.sh
Executable file
3
src/coreutils/chgrp/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
92
src/coreutils/chgrp/chgrp.c
Normal file
92
src/coreutils/chgrp/chgrp.c
Normal file
@ -0,0 +1,92 @@
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include "make_path.h"
|
||||
#include "get_stat.h"
|
||||
#include "recurse.h"
|
||||
|
||||
char r_flag;
|
||||
char *f_flag = "chgrp";
|
||||
char H_flag;
|
||||
char v_flag;
|
||||
|
||||
int change(const char *path, void *p) {
|
||||
struct group *grp = (struct group *)p;
|
||||
|
||||
struct stat stat_path;
|
||||
if (mu_get_stat(f_flag, path, &stat_path))
|
||||
return 1;
|
||||
|
||||
if (lchown(path, stat_path.st_uid, grp->gr_gid)) {
|
||||
if (f_flag)
|
||||
fprintf(stderr, "chgrp: %s: %s\n", path, strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (v_flag)
|
||||
printf("chgrp: %s: changed group to %s\n", path, grp->gr_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "RfHv")) != -1) {
|
||||
switch (opt) {
|
||||
case 'R':
|
||||
r_flag = 1;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
f_flag = NULL;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
H_flag = 1;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
v_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("chgrp [RfHv] [group] [file1 file2...]\n\t-H Symbolic link\n\t-R Recursive\n\t-f Silent\n\t-v Verbose\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc == 0) {
|
||||
fprintf(stderr, "chgrp: missing operand\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct group *grp = getgrnam(argv[0]);
|
||||
if (!grp) {
|
||||
if (f_flag)
|
||||
fprintf(stderr, "chgrp: unknow group\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (r_flag) {
|
||||
if (mu_recurse(f_flag, H_flag, argv[i], (void *)grp, change, change))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
else
|
||||
ret = change(argv[i], grp);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
3
src/coreutils/chmod/build.sh
Executable file
3
src/coreutils/chmod/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
103
src/coreutils/chmod/chmod.c
Normal file
103
src/coreutils/chmod/chmod.c
Normal file
@ -0,0 +1,103 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include "mode_to_str.h"
|
||||
#include "make_path.h"
|
||||
#include "get_stat.h"
|
||||
#include "parse_mode.h"
|
||||
#include "recurse.h"
|
||||
|
||||
char r_flag;
|
||||
char *f_flag = "chmod";
|
||||
char H_flag;
|
||||
char v_flag;
|
||||
|
||||
int change(const char *file, void *p) {
|
||||
char *mode_arg = (char *)p;
|
||||
|
||||
struct stat sb;
|
||||
if (mu_get_stats(f_flag, H_flag, file, &sb))
|
||||
return 1;
|
||||
|
||||
mode_t mode = mu_parse_mode(mode_arg, sb.st_mode);
|
||||
if (chmod(file, mode) != 0) {
|
||||
if (f_flag)
|
||||
fprintf(stderr, "chmod: unable to chown %s: %s\n", file, strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (v_flag)
|
||||
printf("chmod: %s: changed mode to %s\n", file, mu_mode_2_str(mode));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
/* Arg hacking */
|
||||
char *arg = NULL;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (argv[i][0] != '-' || strlen(argv[i]) <= 1)
|
||||
break;
|
||||
|
||||
else if (argv[i][1] == 'x' || argv[i][1] == 'r' || argv[i][1] == 'w') {
|
||||
argv[i][0] = 'a';
|
||||
arg = argv[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "RfHv")) != -1) {
|
||||
switch (opt) {
|
||||
case 'R':
|
||||
r_flag = 1;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
f_flag = NULL;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
H_flag = 1;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
v_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("chmod [RfHv] [ugoa]{+|-}[rwxXst] / [0 - 777] [file1 file2...]\n\t-H Symbolic link\n\t-R Recursive\n\t-f Silent\n\t-v Verbose\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc == 0) {
|
||||
fprintf(stderr, "chmod: missing operand\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Restore arg */
|
||||
if (arg)
|
||||
arg[0] = '-';
|
||||
|
||||
int ret = 0;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (r_flag) {
|
||||
if (mu_recurse(f_flag, H_flag, argv[i], argv[0], change, change))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
else
|
||||
change(argv[i], argv[0]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
3
src/coreutils/chown/build.sh
Executable file
3
src/coreutils/chown/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
131
src/coreutils/chown/chown.c
Normal file
131
src/coreutils/chown/chown.c
Normal file
@ -0,0 +1,131 @@
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "make_path.h"
|
||||
#include "get_stat.h"
|
||||
#include "recurse.h"
|
||||
#include "unused.h"
|
||||
|
||||
char r_flag;
|
||||
char *f_flag = "chown";
|
||||
char H_flag;
|
||||
char v_flag;
|
||||
int (*chown_func)(const char *pathname, uid_t owner, gid_t group);
|
||||
long gid;
|
||||
long uid;
|
||||
|
||||
int change(const char *path, void *p) {
|
||||
char *name = (char *)p;
|
||||
|
||||
if (chown_func(path, uid, gid)) {
|
||||
if (f_flag)
|
||||
fprintf(stderr, "chown: unable to chown %s: %s\n", path, strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (v_flag)
|
||||
printf("chown: %s: changed to %s\n", path, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void get_owner(const char *arg) {
|
||||
char *group = strchr(arg, ':');
|
||||
|
||||
char g_flag = 1;
|
||||
char u_flag = 1;
|
||||
|
||||
if (group == arg)
|
||||
u_flag = 0;
|
||||
|
||||
else if (!group)
|
||||
g_flag = 0;
|
||||
|
||||
if (g_flag) {
|
||||
group[0] = '\0';
|
||||
group++;
|
||||
|
||||
struct group *grp = getgrnam(group);
|
||||
if (!grp) {
|
||||
if (f_flag)
|
||||
fprintf(stderr, "chown: invalid group: %s\n", group);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
gid = grp->gr_gid;
|
||||
}
|
||||
|
||||
if (u_flag) {
|
||||
struct passwd *pwd = getpwnam(arg);
|
||||
if (!pwd) {
|
||||
if (f_flag)
|
||||
fprintf(stderr, "chown: invalid user: %s\n", arg);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uid = pwd->pw_gid;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
chown_func = lchown;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "RfHv")) != -1) {
|
||||
switch (opt) {
|
||||
case 'R':
|
||||
r_flag = 1;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
f_flag = NULL;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
H_flag = 1;
|
||||
chown_func = chown;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
v_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("chown [RfHf] USER[:[GRP]] [file1 file2...]\n\t-H Symbolic link\n\t-R Recursive\n\t-f Silent\n\t-v Verbose\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc == 0) {
|
||||
fprintf(stderr, "chown: missing operand\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
gid = -1;
|
||||
uid = -1;
|
||||
get_owner(argv[0]);
|
||||
|
||||
int ret = 0;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (r_flag) {
|
||||
if (mu_recurse(f_flag, H_flag, argv[i], argv[0], change, change))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
else
|
||||
ret = change(argv[i], argv[0]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
3
src/coreutils/chroot/build.sh
Executable file
3
src/coreutils/chroot/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
29
src/coreutils/chroot/chroot.c
Normal file
29
src/coreutils/chroot/chroot.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main(const int argc, char **argv) {
|
||||
if (argc < 3 || !strcmp(argv[argc - 1], "--help")) {
|
||||
printf("chroot [dir] [command] [arg arg2...]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (chroot(argv[1]) < 0) {
|
||||
fprintf(stderr, "chroot: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (chdir("/") < 0) {
|
||||
fprintf(stderr, "chroot: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (execvp(argv[2], argv + 2) < 0) {
|
||||
fprintf(stderr, "chroot: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
3
src/coreutils/cmp/build.sh
Executable file
3
src/coreutils/cmp/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
126
src/coreutils/cmp/cmp.c
Normal file
126
src/coreutils/cmp/cmp.c
Normal file
@ -0,0 +1,126 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
char s_flag;
|
||||
|
||||
int compare(FILE *fp1, FILE *fp2) {
|
||||
if (fp1 == fp2)
|
||||
return 0;
|
||||
|
||||
int ch1;
|
||||
int ch2;
|
||||
|
||||
size_t byte = 1;
|
||||
size_t lines = 1;
|
||||
do {
|
||||
ch1 = getc(fp1);
|
||||
ch2 = getc(fp2);
|
||||
|
||||
if (ch1 != ch2) {
|
||||
if (!s_flag)
|
||||
printf("files differ at byte %zu and line %zu\n", byte, lines);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ch1 == '\n')
|
||||
lines++;
|
||||
|
||||
byte++;
|
||||
} while(ch1 != EOF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long parse_int(const char *str) {
|
||||
char *ptr;
|
||||
long val = strtol(str, &ptr, 0);
|
||||
if (*ptr || val < 0) {
|
||||
fprintf(stderr, "cmp: invalid offset: %s\n", str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
FILE *file_open(const char *path) {
|
||||
if (!strcmp(path, "-"))
|
||||
return stdin;
|
||||
|
||||
FILE *fp = fopen(path, "r");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "cmp: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "s")) != -1) {
|
||||
switch (opt) {
|
||||
case 's':
|
||||
s_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("cmp [s] [file1] [file2] [skip1] [skip2]\n\t-s Silent\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
long skip1 = 0;
|
||||
long skip2 = 0;
|
||||
FILE *fp1 = NULL;
|
||||
FILE *fp2 = stdin;
|
||||
|
||||
switch (argc) {
|
||||
case 4:
|
||||
skip2 = parse_int(argv[3]);
|
||||
/* fallthrough */
|
||||
|
||||
case 3:
|
||||
skip1 = parse_int(argv[2]);
|
||||
/* fallthrough */
|
||||
|
||||
case 2:
|
||||
fp2 = file_open(argv[1]);
|
||||
/* fallthrough */
|
||||
|
||||
case 1:
|
||||
fp1 = file_open(argv[0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "cmp: missing operand\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (skip1 && fseek(fp1, skip1, SEEK_SET) < 0) {
|
||||
if (!s_flag)
|
||||
fprintf(stderr, "cmp: %s\n", strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (skip2 && fseek(fp2, skip2, SEEK_SET) < 0) {
|
||||
if (!s_flag)
|
||||
fprintf(stderr, "cmp: %s\n", strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ret = compare(fp1, fp2);
|
||||
fclose(fp1);
|
||||
fclose(fp2);
|
||||
|
||||
return ret;
|
||||
}
|
3
src/coreutils/cp/build.sh
Executable file
3
src/coreutils/cp/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
213
src/coreutils/cp/cp.c
Normal file
213
src/coreutils/cp/cp.c
Normal file
@ -0,0 +1,213 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <limits.h>
|
||||
#include <sys/mman.h>
|
||||
#include "make_path.h"
|
||||
#include "get_stat.h"
|
||||
#include "config.h"
|
||||
|
||||
char *f_flag = "cp";
|
||||
char r_flag;
|
||||
char v_flag;
|
||||
char L_flag;
|
||||
|
||||
char copy_reg(int mode, const char *src, const char *dst) {
|
||||
int ret = 1;
|
||||
|
||||
int ifd = open(src, O_RDONLY);
|
||||
if (ifd < 0)
|
||||
return 1;
|
||||
|
||||
int ofd = open(dst, O_WRONLY | O_TRUNC | O_CREAT, mode);
|
||||
if (ofd < 0)
|
||||
goto CLOSE_OFD;
|
||||
|
||||
char buf[BUF_SIZE + 1];
|
||||
while (1) {
|
||||
ssize_t n = read(ifd, buf, sizeof(buf));
|
||||
if (n <= 0) {
|
||||
if (n < 0)
|
||||
goto CLOSE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (write(ofd, buf, n) != n)
|
||||
goto CLOSE;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
CLOSE:
|
||||
close(ofd);
|
||||
|
||||
CLOSE_OFD:
|
||||
close(ifd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char copy_lnk(const char *src, const char *dst) {
|
||||
char path[PATH_MAX + 1];
|
||||
ssize_t ret = readlink(src, path, sizeof(path));
|
||||
if (ret < 0)
|
||||
return 1;
|
||||
|
||||
path[ret] = '\0';
|
||||
if (symlink(path, dst) < 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char copy(struct stat st, const char *src, const char *dst) {
|
||||
if (v_flag)
|
||||
printf("Copying '%s' to '%s'\n", src, dst);
|
||||
|
||||
if (S_ISLNK(st.st_mode))
|
||||
return copy_lnk(src, dst);
|
||||
|
||||
else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || S_ISFIFO(st.st_mode)) {
|
||||
if (mknod(dst, st.st_mode, st.st_dev) < 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
else
|
||||
return copy_reg(st.st_mode, src, dst);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cptree(const char *src, const char *dst) {
|
||||
struct stat src_stat;
|
||||
if (mu_get_stats(f_flag, !L_flag, src, &src_stat))
|
||||
return 1;
|
||||
|
||||
if (!S_ISDIR(src_stat.st_mode)) {
|
||||
if (copy(src_stat, src, dst)) {
|
||||
if (f_flag)
|
||||
fprintf(stderr, "cp: %s: %s\n", dst, strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
else if (!r_flag) {
|
||||
if (f_flag)
|
||||
fprintf(stderr, "cp: omitting directory: %s\n", dst);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
else if (mkdir(dst, 0777) < 0) {
|
||||
if (f_flag)
|
||||
fprintf(stderr, "cp: %s: %s\n", dst, strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
DIR *dir = opendir(src);
|
||||
if (dir == NULL) {
|
||||
if (f_flag)
|
||||
fprintf(stderr, "cp: %s: Can`t open directory\n", src);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
|
||||
struct dirent *ep;
|
||||
while ((ep = readdir(dir)) != NULL) {
|
||||
if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..") || !strcmp(dst, ep->d_name))
|
||||
continue;
|
||||
|
||||
/* Copy */
|
||||
char *src_path = mu_make_path(f_flag, src, ep->d_name);
|
||||
if (src_path == NULL)
|
||||
continue;
|
||||
|
||||
char *dst_path = mu_make_path(f_flag, dst, ep->d_name);
|
||||
if (dst_path == NULL) {
|
||||
free(src_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cptree(src_path, dst_path))
|
||||
ret = 1;
|
||||
|
||||
free(src_path);
|
||||
free(dst_path);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "frvL")) != -1) {
|
||||
switch (opt) {
|
||||
case 'f':
|
||||
f_flag = NULL;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
r_flag = 1;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
v_flag = 1;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
L_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("cp [frvL] [src1 src2...] [dst]\n\t-f Silent\n\t-r Recursive\n\t-v Verbose\n\t-L Follow all symlinks\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "cp: missing operand\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
struct stat sb;
|
||||
if (!mu_get_stat(NULL, argv[argc - 1], &sb))
|
||||
if (S_ISDIR(sb.st_mode))
|
||||
goto IF_EXSIST;
|
||||
|
||||
if (argc == 2)
|
||||
ret = cptree(argv[0], argv[argc - 1]);
|
||||
|
||||
else {
|
||||
IF_EXSIST:
|
||||
for (int i = 0; i < argc - 1; i++) {
|
||||
char *new_path = mu_make_path(f_flag, argv[argc - 1], basename(argv[i]));
|
||||
if (new_path == NULL)
|
||||
return 1;
|
||||
|
||||
if (cptree(argv[i], new_path))
|
||||
ret = 1;
|
||||
|
||||
free(new_path);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
3
src/coreutils/date/build.sh
Executable file
3
src/coreutils/date/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
109
src/coreutils/date/date.c
Normal file
109
src/coreutils/date/date.c
Normal file
@ -0,0 +1,109 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include "get_stat.h"
|
||||
|
||||
const char *fmts[] = {
|
||||
"%R",
|
||||
"%T",
|
||||
"%m.%d-%R",
|
||||
"%m.%d-%T",
|
||||
"%Y.%m.%d-%R",
|
||||
"%Y.%m.%d-%T",
|
||||
"%Y-%m-%d %R %z",
|
||||
"%Y-%m-%d %T %z",
|
||||
"%T %d-%m-%Y",
|
||||
"%H %d-%m-%Y",
|
||||
"%Y-%m-%d %H",
|
||||
"%Y-%m-%d",
|
||||
"%d-%m-%Y"
|
||||
};
|
||||
|
||||
time_t parse_date(char *str) {
|
||||
time_t local = time(NULL);
|
||||
struct tm *tm = localtime(&local);
|
||||
|
||||
for (size_t i = 0; i < sizeof(fmts) / sizeof(char *); i++) {
|
||||
char *res = strptime(str, fmts[i], tm);
|
||||
if (res && *res == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
time_t rt = mktime(tm);
|
||||
if (rt == -1) {
|
||||
fprintf(stderr, "date: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
time_t t = time(NULL);
|
||||
char *fmt = "%a %b %e %H:%M:%S %Z %Y";
|
||||
char *r_flag = 0;
|
||||
|
||||
/* For -s flag */
|
||||
struct timespec ts;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "s:d:r:u")) != -1) {
|
||||
switch (opt) {
|
||||
case 'r':
|
||||
r_flag = optarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
ts.tv_sec = parse_date(optarg);
|
||||
if (clock_settime(CLOCK_REALTIME, &ts) < 0) {
|
||||
fprintf(stderr, "date: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
case 'd':
|
||||
t = parse_date(optarg);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
if (setenv("TZ", "UTC0", 1) < 0) {
|
||||
fprintf(stderr, "date: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("date [rsdu] [+\"fmt\"]\n\t-s DATE Set new date\n\t-d DATE Print new date\n\t-u Work in UTC\n\t-r FILE Display last modification time of FILE\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc != 0)
|
||||
if (argv[0][0] == '+')
|
||||
fmt = argv[0] + 1;
|
||||
|
||||
struct stat sb;
|
||||
if (r_flag) {
|
||||
if (mu_get_stat("date", r_flag, &sb))
|
||||
return 1;
|
||||
|
||||
t = sb.st_mtime;
|
||||
}
|
||||
|
||||
struct tm *tm = localtime(&t);
|
||||
|
||||
char buf[256];
|
||||
strftime(buf, sizeof(buf), fmt, tm);
|
||||
|
||||
puts(buf);
|
||||
return 0;
|
||||
}
|
3
src/coreutils/dd/build.sh
Executable file
3
src/coreutils/dd/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
249
src/coreutils/dd/dd.c
Normal file
249
src/coreutils/dd/dd.c
Normal file
@ -0,0 +1,249 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "human.h"
|
||||
|
||||
off_t infull, inpart;
|
||||
off_t outfull, outpart;
|
||||
off_t tbytes;
|
||||
|
||||
void summary(void) {
|
||||
fprintf(stderr, "%jd+%jd records in\n", infull, inpart);
|
||||
fprintf(stderr, "%jd+%jd records out\n", outfull, outpart);
|
||||
|
||||
fprintf(stderr, "%s total bytes copied\n", mu_humansize(tbytes, 1024));
|
||||
}
|
||||
|
||||
int openfile(int flag, char *path, int mode) {
|
||||
if (!strcmp(path, "-")) {
|
||||
if (flag)
|
||||
return STDOUT_FILENO;
|
||||
|
||||
return STDIN_FILENO;
|
||||
}
|
||||
|
||||
int fd = open(path, mode, 0666);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "dd: %s: %s\n", path, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
off_t strtonum(char *str) {
|
||||
char *p = NULL;
|
||||
off_t res = strtoll(str, &p, 0);
|
||||
if (str != p) {
|
||||
if (!strcmp(p, "b"))
|
||||
res *= 512;
|
||||
|
||||
else if (!strcmp(p, "m"))
|
||||
res *= 1000000;
|
||||
|
||||
else if (!strcmp(p, "M"))
|
||||
res *= 1048576;
|
||||
|
||||
else if (!strcmp(p, "K"))
|
||||
res *= 1024;
|
||||
|
||||
else if (!strcmp(p, "k"))
|
||||
res *= 1000;
|
||||
|
||||
else if (!strcmp(p, "g"))
|
||||
res *= 1000000000;
|
||||
|
||||
else if (!strcmp(p, "G"))
|
||||
res *= 1073741824;
|
||||
}
|
||||
|
||||
if (res < 0)
|
||||
res = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int copy(int fd, void *buf, off_t len, off_t max) {
|
||||
off_t n = write(fd, buf, len);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "dd: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
else if (n == max)
|
||||
outfull++;
|
||||
|
||||
else if (n == len)
|
||||
outpart++;
|
||||
|
||||
tbytes += n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
char *ifp = "-";
|
||||
char *ofp = "-";
|
||||
|
||||
off_t count = -1;
|
||||
off_t skip = 0;
|
||||
off_t seek = 0;
|
||||
|
||||
off_t bs = 0;
|
||||
off_t ibs = 512;
|
||||
off_t obs = 512;
|
||||
|
||||
int ofd = STDOUT_FILENO;
|
||||
int ifd = STDIN_FILENO;
|
||||
|
||||
/* Return value */
|
||||
int ret = 1;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
char *arg = argv[i];
|
||||
|
||||
char *val = strchr(arg, '=');
|
||||
if (val == NULL) {
|
||||
printf("dd\n\tif=InputFile\n\tof=OutputFile\n\tbs=ibs and obs\n\tibs=Input buffer size\n\tobs=Output buffer size\n\tseek=Skip N obs-sized output blocks\n\tskip=Skip N ibs-sized output blocks\n\tcount=Copy only N input blocks\n\nN and BYTES may be followed by the following multiplicative\nsuffixes: w=2, b=512, k=1000, K=1024, m=1000*1000,\nM=1024*1024, g=1000*1000*1000, G=1024*1024*1024\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
*val = '\0';
|
||||
val++;
|
||||
|
||||
/* Get value */
|
||||
if (!strcmp(arg, "if"))
|
||||
ifp = val;
|
||||
|
||||
else if (!strcmp(arg, "of"))
|
||||
ofp = val;
|
||||
|
||||
else if (!strcmp(arg, "seek"))
|
||||
seek = strtonum(val);
|
||||
|
||||
else if (!strcmp(arg, "skip"))
|
||||
skip = strtonum(val);
|
||||
|
||||
else if (!strcmp(arg, "count"))
|
||||
count = strtonum(val);
|
||||
|
||||
else if (!strcmp(arg, "bs"))
|
||||
bs = strtonum(val);
|
||||
|
||||
else if (!strcmp(arg, "ibs"))
|
||||
ibs = strtonum(val);
|
||||
|
||||
else if (!strcmp(arg, "obs"))
|
||||
obs = strtonum(val);
|
||||
}
|
||||
|
||||
if (bs) {
|
||||
ibs = bs;
|
||||
obs = bs;
|
||||
}
|
||||
|
||||
/* Make input ibuffer */
|
||||
char *ibuf = malloc(ibs);
|
||||
if (ibuf == NULL) {
|
||||
fprintf(stderr, "dd: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *obuf = NULL;
|
||||
if (ibs != obs) {
|
||||
obuf = malloc(obs);
|
||||
if (obuf == NULL) {
|
||||
free(ibuf);
|
||||
fprintf(stderr, "dd: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Open files. Input */
|
||||
ifd = openfile(0, ifp, O_RDONLY);
|
||||
if (skip) {
|
||||
if (lseek(ifd, skip * ibs, SEEK_CUR) < 0)
|
||||
goto CLOSE;
|
||||
}
|
||||
|
||||
/* Output */
|
||||
int oflag = O_WRONLY | O_CREAT;
|
||||
if (seek)
|
||||
oflag |= O_TRUNC;
|
||||
|
||||
ofd = openfile(1, ofp, oflag);
|
||||
if (seek) {
|
||||
if (ftruncate(ofd, seek * ibs) < 0 || lseek(ofd, seek * ibs, SEEK_SET) < 0) {
|
||||
fprintf(stderr, "dd: %s\n", strerror(errno));
|
||||
goto CLOSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* dd */
|
||||
off_t opos = 0;
|
||||
|
||||
while (1) {
|
||||
if (count == infull + inpart)
|
||||
break;
|
||||
|
||||
off_t n = read(ifd, ibuf, ibs);
|
||||
if (n <= 0)
|
||||
break;
|
||||
|
||||
else if (ibs == n)
|
||||
infull++;
|
||||
|
||||
else
|
||||
inpart++;
|
||||
|
||||
if (ibs == obs) {
|
||||
if (copy(ofd, ibuf, n, ibs))
|
||||
goto CLOSE;
|
||||
}
|
||||
|
||||
else {
|
||||
char *tmp = ibuf;
|
||||
while (n) {
|
||||
off_t i = obs - opos;
|
||||
if (i > n)
|
||||
i = n;
|
||||
|
||||
memcpy(obuf + opos, tmp, i);
|
||||
|
||||
n -= i;
|
||||
tmp += i;
|
||||
opos += i;
|
||||
if (opos == obs) {
|
||||
if (copy(ofd, obuf, obs, obs))
|
||||
goto CLOSE;
|
||||
|
||||
opos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (opos != 0) {
|
||||
if (copy(ofd, obuf, obs, obs))
|
||||
goto CLOSE;
|
||||
}
|
||||
|
||||
/* End */
|
||||
fsync(ofd);
|
||||
summary();
|
||||
|
||||
ret = 0;
|
||||
|
||||
CLOSE:
|
||||
free(ibuf);
|
||||
if (ibs != obs)
|
||||
free(obuf);
|
||||
|
||||
close(ifd);
|
||||
close(ofd);
|
||||
return ret;
|
||||
}
|
3
src/coreutils/df/build.sh
Executable file
3
src/coreutils/df/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
95
src/coreutils/df/df.c
Normal file
95
src/coreutils/df/df.c
Normal file
@ -0,0 +1,95 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <mntent.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include "human.h"
|
||||
#include "config.h"
|
||||
|
||||
char a_flag;
|
||||
char h_flag;
|
||||
off_t block = 1024;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "hHka")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
h_flag = 1;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
h_flag = 1;
|
||||
block = 1000;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
a_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("df [rHa]\n\t-h Human readable (1024)\n\t-a Show all\n\t-H Human readable (1000)\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
FILE *fp = setmntent("/proc/mounts", "r");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "df: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (h_flag)
|
||||
puts("Filesystem Size Used Available Use% Mounted on");
|
||||
|
||||
else
|
||||
puts("Filesystem Size Used Available Use% Mounted on");
|
||||
|
||||
|
||||
int ret = 0;
|
||||
struct mntent *me;
|
||||
struct statvfs disk;
|
||||
|
||||
while ((me = getmntent(fp)) != NULL) {
|
||||
if (!strcmp(me->mnt_fsname, "none"))
|
||||
continue;
|
||||
|
||||
if (statvfs(me->mnt_dir, &disk) < 0) {
|
||||
ret = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!a_flag)
|
||||
if (!strcmp(me->mnt_fsname, "/dev/root") || disk.f_blocks == 0)
|
||||
continue;
|
||||
|
||||
off_t bs = disk.f_frsize / block;
|
||||
off_t total = disk.f_blocks * bs;
|
||||
off_t avail = disk.f_bfree * bs;
|
||||
off_t used = total - avail;
|
||||
off_t capacity = (used * 100 + 1) / (avail + used + 1);
|
||||
|
||||
if (!h_flag)
|
||||
printf("%-20s %12jd %12jd %12jd %12jd%% %s\n", me->mnt_fsname, total, used, avail, capacity, me->mnt_dir);
|
||||
|
||||
else {
|
||||
char total_s[MU_HUMAN_BUF_SIZE + 1];
|
||||
char used_s[MU_HUMAN_BUF_SIZE + 1];
|
||||
char avail_s[MU_HUMAN_BUF_SIZE + 1];
|
||||
|
||||
snprintf(total_s, sizeof(total_s), "%s", mu_humansize(total * block, block));
|
||||
snprintf(used_s, sizeof(used_s), "%s", mu_humansize(used * block, block));
|
||||
snprintf(avail_s, sizeof(avail_s), "%s", mu_humansize(avail * block, block));
|
||||
|
||||
printf("%-20s %10s %9s %9s %3jd%% %s\n", me->mnt_fsname, total_s, used_s, avail_s, capacity, me->mnt_dir);
|
||||
}
|
||||
}
|
||||
|
||||
endmntent(fp);
|
||||
return ret;
|
||||
}
|
||||
|
3
src/coreutils/du/build.sh
Executable file
3
src/coreutils/du/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
111
src/coreutils/du/du.c
Normal file
111
src/coreutils/du/du.c
Normal file
@ -0,0 +1,111 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <stdint.h>
|
||||
#include "get_stat.h"
|
||||
#include "make_path.h"
|
||||
#include "human.h"
|
||||
|
||||
char h_flag;
|
||||
char s_flag;
|
||||
char c_flag;
|
||||
off_t total;
|
||||
|
||||
void print(off_t size, const char *filename) {
|
||||
if (h_flag)
|
||||
printf("%s\t%s\n", mu_humansize(size * 512, 1024), filename);
|
||||
|
||||
else
|
||||
printf("%jd\t%s\n", (intmax_t)size / 2, filename);
|
||||
}
|
||||
|
||||
off_t du(const char *path, int recurs_flag) {
|
||||
struct stat sb;
|
||||
if (mu_get_lstat("du", path, &sb))
|
||||
return 0;
|
||||
|
||||
off_t sum = sb.st_blocks;
|
||||
if (c_flag)
|
||||
total += sum;
|
||||
|
||||
if (S_ISDIR(sb.st_mode)) {
|
||||
DIR *dp = opendir(path);
|
||||
if (!dp) {
|
||||
fprintf(stderr, "du: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dirent *ep;
|
||||
while ((ep = readdir(dp)) != NULL) {
|
||||
if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, ".."))
|
||||
continue;
|
||||
|
||||
char *new_path = mu_make_path("du", path, ep->d_name);
|
||||
if (new_path == NULL)
|
||||
return 0;
|
||||
|
||||
sum += du(new_path, 1);
|
||||
|
||||
free(new_path);
|
||||
}
|
||||
|
||||
closedir(dp);
|
||||
|
||||
if (!s_flag && recurs_flag) {
|
||||
print(sum, path);
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* Silent mode */
|
||||
else if (!recurs_flag)
|
||||
print(sum, path);
|
||||
}
|
||||
|
||||
else if (!recurs_flag)
|
||||
print(sum, path);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "hsc")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
h_flag = 1;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
s_flag = 1;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
c_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("du [hsc] [src1 src2...]\n\t-h Sizes in human readable format\n\t-s Display only a total for each argument\n\t-c produce a grand total\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (argv[optind] == NULL)
|
||||
du(".", 0);
|
||||
|
||||
else {
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
for (int i = 0; i < argc; i++)
|
||||
du(argv[i], 0);
|
||||
|
||||
}
|
||||
|
||||
if (c_flag)
|
||||
print(total, "total");
|
||||
|
||||
return 0;
|
||||
}
|
3
src/coreutils/echo/build.sh
Executable file
3
src/coreutils/echo/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
94
src/coreutils/echo/echo.c
Normal file
94
src/coreutils/echo/echo.c
Normal file
@ -0,0 +1,94 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
char n_flag = 0;
|
||||
char e_flag = 0;
|
||||
|
||||
void format(char *str) {
|
||||
for (size_t i = 0; i < strlen(str); i++) {
|
||||
unsigned int c = str[i];
|
||||
if (c == '\\') {
|
||||
switch (str[i + 1]) {
|
||||
case 'a':
|
||||
c = '\a';
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
c = '\n';
|
||||
break;
|
||||
|
||||
case 't':
|
||||
c = '\t';
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
exit(0);
|
||||
|
||||
case 'v':
|
||||
c = '\v';
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
c = '\r';
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
c = '\f';
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
c = '\033';
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
c = '\b';
|
||||
break;
|
||||
|
||||
default:
|
||||
c = '\\';
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
putchar(c);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
argv++;
|
||||
argc--;
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
if (strstr(argv[i] + 1, "n"))
|
||||
n_flag = 1;
|
||||
|
||||
else if (strstr(argv[i] + 1, "e"))
|
||||
e_flag = 1;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (e_flag)
|
||||
format(argv[i]);
|
||||
|
||||
else
|
||||
fputs(argv[i], stdout);
|
||||
|
||||
if (i < argc - 1)
|
||||
putchar(' ');
|
||||
}
|
||||
|
||||
if (!n_flag)
|
||||
putchar('\n');
|
||||
|
||||
return 0;
|
||||
}
|
3
src/coreutils/env/build.sh
vendored
Executable file
3
src/coreutils/env/build.sh
vendored
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
33
src/coreutils/env/env.c
vendored
Normal file
33
src/coreutils/env/env.c
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(const int argc, char **argv, const char **envp) {
|
||||
int i;
|
||||
for (i = 1; i < argc; i++) {
|
||||
char *val = strchr(argv[i], '=');
|
||||
if (!val)
|
||||
break;
|
||||
|
||||
val[0] = '\0';
|
||||
|
||||
if (setenv(argv[i], val + 1, 1)) {
|
||||
fprintf(stderr, "env: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print env */
|
||||
if (i == argc) {
|
||||
while (*envp)
|
||||
puts(*envp++);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
execvp(argv[i], argv + i);
|
||||
fprintf(stderr, "env: %s: %s\n", argv[i], strerror(errno));
|
||||
return 1;
|
||||
}
|
3
src/coreutils/false/build.sh
Executable file
3
src/coreutils/false/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
3
src/coreutils/false/false.c
Normal file
3
src/coreutils/false/false.c
Normal file
@ -0,0 +1,3 @@
|
||||
int main(void) {
|
||||
return 1;
|
||||
}
|
3
src/coreutils/head/build.sh
Executable file
3
src/coreutils/head/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
95
src/coreutils/head/head.c
Normal file
95
src/coreutils/head/head.c
Normal file
@ -0,0 +1,95 @@
|
||||
#define _HEAD_C
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "config.h"
|
||||
|
||||
char v_flag;
|
||||
char c_flag;
|
||||
|
||||
long parse_long(const char *str) {
|
||||
char *ptr;
|
||||
long ret = strtol(str, &ptr, 0);
|
||||
if (*ptr) {
|
||||
fprintf(stderr, "head: %s invalid number\n", ptr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void print(const char *file, FILE *fp, long lines, long bytes) {
|
||||
if (v_flag)
|
||||
printf(HEAD_FMT, file);
|
||||
|
||||
long lcount = 0;
|
||||
long bcount = 0;
|
||||
|
||||
while (1) {
|
||||
int c = getc(fp);
|
||||
bcount++;
|
||||
if (c == '\n')
|
||||
lcount++;
|
||||
|
||||
if (c == EOF || lcount == lines || (c_flag && bcount == bytes))
|
||||
break;
|
||||
|
||||
putchar(c);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
long lines = 10;
|
||||
long bytes = 0;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "n:c:v")) != -1) {
|
||||
switch (opt) {
|
||||
case 'n':
|
||||
lines = parse_long(optarg);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
c_flag = 1;
|
||||
bytes = parse_long(optarg);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
v_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("head [ncv] [file1 file2...]\n\t-n Print N lines\n\t-c Print N bytes\n\t-v Print headers\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc == 0)
|
||||
print("-", stdin, lines, bytes);
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
FILE *fp = NULL;
|
||||
if (argv[i][0] == '-')
|
||||
fp = stdin;
|
||||
|
||||
else
|
||||
fp = fopen(argv[i], "r");
|
||||
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "head: %s: %s\n", argv[i], strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
print(argv[i], fp, lines, bytes);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
3
src/coreutils/id/build.sh
Executable file
3
src/coreutils/id/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
130
src/coreutils/id/id.c
Normal file
130
src/coreutils/id/id.c
Normal file
@ -0,0 +1,130 @@
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
char g_flag;
|
||||
char G_flag;
|
||||
char n_flag;
|
||||
char r_flag;
|
||||
char u_flag;
|
||||
|
||||
int print_groups(const struct passwd *pwd, const char *fmt, const int flag) {
|
||||
gid_t groups[NGROUPS_MAX];
|
||||
int ngroups = NGROUPS_MAX;
|
||||
if (getgrouplist(pwd->pw_name, pwd->pw_gid, groups, &ngroups) < 0)
|
||||
return 1;
|
||||
|
||||
for (int i = 0; i < ngroups; i++) {
|
||||
struct group *grp = getgrgid(groups[i]);
|
||||
if (grp && !n_flag)
|
||||
printf("%u", groups[i]);
|
||||
|
||||
if ((!r_flag && n_flag) || flag)
|
||||
printf(fmt, grp->gr_name);
|
||||
|
||||
if (g_flag && i == 0)
|
||||
break;
|
||||
|
||||
putchar(' ');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ids(uid_t uid, struct passwd *pwd) {
|
||||
if (u_flag) {
|
||||
if (n_flag)
|
||||
printf("%s", pwd->pw_name);
|
||||
|
||||
else
|
||||
printf("%u", uid);
|
||||
}
|
||||
|
||||
else if (G_flag || g_flag)
|
||||
print_groups(pwd, "%s", 0);
|
||||
|
||||
putchar('\n');
|
||||
return 0;
|
||||
}
|
||||
|
||||
int def_ids(uid_t uid, struct passwd *pwd) {
|
||||
printf("uid=%d(%s) gid=%d", uid, pwd->pw_name, pwd->pw_gid);
|
||||
struct group *grp = getgrgid(pwd->pw_gid);
|
||||
if (grp)
|
||||
printf("(%s)", grp->gr_name);
|
||||
|
||||
printf(" groups=");
|
||||
print_groups(pwd, "(%s)", 1);
|
||||
|
||||
putchar('\n');
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usage(int sig) {
|
||||
printf("id [gGurn] [user]\n\t-u User ID\n\t-g Group ID\n\t-G Supplementary group IDs\n\t-n Print names instead of numbers\n\t-r Print real ID instead of effective ID\n");
|
||||
exit(sig);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "gGnru")) != -1) {
|
||||
switch (opt) {
|
||||
case 'g':
|
||||
if (G_flag || u_flag)
|
||||
usage(1);
|
||||
|
||||
g_flag = 1;
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
if (g_flag || u_flag)
|
||||
usage(1);
|
||||
|
||||
G_flag = 1;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
if (G_flag || g_flag)
|
||||
usage(1);
|
||||
|
||||
u_flag = 1;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
r_flag = 1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
n_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(0);
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
uid_t uid = getuid();
|
||||
struct passwd *pwd = getpwuid(uid);
|
||||
if (argv[0] != NULL)
|
||||
pwd = getpwnam(argv[0]);
|
||||
|
||||
if (!pwd) {
|
||||
fprintf(stderr, "id: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (u_flag || G_flag || g_flag)
|
||||
return ids(uid, pwd);
|
||||
|
||||
return def_ids(uid, pwd);
|
||||
}
|
3
src/coreutils/ln/build.sh
Executable file
3
src/coreutils/ln/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
76
src/coreutils/ln/ln.c
Normal file
76
src/coreutils/ln/ln.c
Normal file
@ -0,0 +1,76 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "make_path.h"
|
||||
|
||||
char s_flag;
|
||||
char f_flag;
|
||||
char v_flag;
|
||||
|
||||
int ln(const char *src, const char *dst) {
|
||||
if (f_flag)
|
||||
if (unlink(dst) && v_flag)
|
||||
fprintf(stderr, "ln: removed %s\n", dst);
|
||||
|
||||
int ret = 0;
|
||||
if (s_flag)
|
||||
ret = symlink(src, dst);
|
||||
|
||||
else
|
||||
ret = link(src, dst);
|
||||
|
||||
if (!ret && v_flag)
|
||||
fprintf(stderr, "ln: linked %s to %s\n", src, dst);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "sfv")) != -1) {
|
||||
switch (opt) {
|
||||
case 's':
|
||||
s_flag = 1;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
f_flag = 1;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
v_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ln [sfv] [src] [dst]\n\t-f Force\n\t-s Symbolic\n\t-v Verbose\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc == 2) {
|
||||
if (ln(argv[0], argv[1])) {
|
||||
char *new_path = mu_make_path("ln", argv[1], argv[0]);
|
||||
if (new_path == NULL)
|
||||
return 1;
|
||||
|
||||
if (ln(argv[0], new_path)) {
|
||||
free(new_path);
|
||||
fprintf(stderr, "ln: %s %s\n", argv[1], strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(new_path);
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
fprintf(stderr, "ln: missing operand\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
3
src/coreutils/ls/build.sh
Executable file
3
src/coreutils/ls/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
508
src/coreutils/ls/ls.c
Normal file
508
src/coreutils/ls/ls.c
Normal file
@ -0,0 +1,508 @@
|
||||
#define _LS_C
|
||||
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "mode_to_str.h"
|
||||
#include "utf8_strlen.h"
|
||||
#include "make_path.h"
|
||||
#include "get_stat.h"
|
||||
#include "config.h"
|
||||
#include "human.h"
|
||||
|
||||
char O_flag;
|
||||
char a_flag;
|
||||
char l_flag;
|
||||
char F_flag;
|
||||
char c_flag;
|
||||
char R_flag;
|
||||
char d_flag;
|
||||
char L_flag;
|
||||
char h_flag;
|
||||
char s_flag;
|
||||
char i_flag;
|
||||
char p_flag;
|
||||
char nul_flag;
|
||||
|
||||
int sortd(const void *p1, const void *p2);
|
||||
int (*sorter)(const void *p1, const void *p2) = sortd;
|
||||
|
||||
struct d_node {
|
||||
/* basename */
|
||||
char *name;
|
||||
|
||||
/* For free */
|
||||
char *full_name;
|
||||
|
||||
struct d_node *next;
|
||||
struct stat stats;
|
||||
};
|
||||
|
||||
/* Work with dir */
|
||||
struct d_node *stat_file(char *filename, const int lfile) {
|
||||
/* lfile its flag. 1 if passed file from list_one() */
|
||||
struct d_node *file = malloc(sizeof(struct d_node));
|
||||
if (file == NULL) {
|
||||
fprintf(stderr, "ls: malloc: %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mu_get_stats("ls", !L_flag, filename, &file->stats)) {
|
||||
free(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
file->full_name = filename;
|
||||
file->name = strrchr(filename, '/');
|
||||
if (file->name == NULL || lfile)
|
||||
file->name = filename;
|
||||
|
||||
else
|
||||
file->name++;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
void dfree(struct d_node **dir, const size_t files) {
|
||||
for (size_t i = 0; i < files; i++) {
|
||||
if (dir[i]->full_name != NULL)
|
||||
free(dir[i]->full_name);
|
||||
|
||||
if (dir[i] != NULL)
|
||||
free(dir[i]);
|
||||
}
|
||||
|
||||
free(dir);
|
||||
}
|
||||
|
||||
struct d_node **list(const char *path, off_t *total_size, size_t *nfiles, int *ret) {
|
||||
DIR *dp = opendir(path);
|
||||
if (dp == NULL) {
|
||||
fprintf(stderr, "ls: %s: %s\n", path, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct d_node **dn = malloc(sizeof(struct d_node *));
|
||||
if (dn == NULL) {
|
||||
fprintf(stderr, "ls: malloc: %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct dirent *ep;
|
||||
while ((ep = readdir(dp)) != NULL) {
|
||||
if (ep->d_name[0] == '.' && !a_flag)
|
||||
continue;
|
||||
|
||||
char *full_path = mu_make_path("ls", path, ep->d_name);
|
||||
if (full_path == NULL)
|
||||
continue;
|
||||
|
||||
struct d_node **bckp = realloc(dn, sizeof(struct d_node *) * (*nfiles + 1));
|
||||
if (bckp == NULL) {
|
||||
free(full_path);
|
||||
dfree(dn, *nfiles);
|
||||
closedir(dp);
|
||||
|
||||
fprintf(stderr, "ls: realloc: %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dn = bckp;
|
||||
|
||||
dn[*nfiles] = stat_file(full_path, 0);
|
||||
if (dn[*nfiles] == NULL) {
|
||||
*ret = 1;
|
||||
free(full_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
*total_size += dn[*nfiles]->stats.st_blocks;
|
||||
(*nfiles)++;
|
||||
}
|
||||
|
||||
closedir(dp);
|
||||
return dn;
|
||||
}
|
||||
|
||||
char *get_date(const time_t mtime) {
|
||||
static char date[100];
|
||||
|
||||
strftime(date, sizeof(date), "%b %d %H:%M", localtime(&mtime));
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
/* Print */
|
||||
int print(const struct d_node *node) {
|
||||
char suf = ' ';
|
||||
char *color = "";
|
||||
|
||||
char *mode = mu_mode_2_str(node->stats.st_mode);
|
||||
if (S_ISDIR(node->stats.st_mode)) {
|
||||
if (node->name[strlen(node->name) - 1] != '/')
|
||||
suf = '/';
|
||||
|
||||
mode[0] = 'd';
|
||||
color = LS_DIR_COLOR;
|
||||
}
|
||||
|
||||
else if (S_ISLNK(node->stats.st_mode)) {
|
||||
suf = '@';
|
||||
mode[0] = 'l';
|
||||
color = LS_LINK_COLOR;
|
||||
}
|
||||
|
||||
else if (S_ISSOCK(node->stats.st_mode)) {
|
||||
suf = '=';
|
||||
mode[0] = 's';
|
||||
color = LS_SOCK_COLOR;
|
||||
}
|
||||
|
||||
else if (S_ISBLK(node->stats.st_mode)) {
|
||||
mode[0] = 'b';
|
||||
color = LS_BLOCK_COLOR;
|
||||
}
|
||||
|
||||
else if (S_ISFIFO(node->stats.st_mode)) {
|
||||
suf = '|';
|
||||
mode[0] = 'p';
|
||||
color = LS_FIFO_COLOR;
|
||||
}
|
||||
|
||||
else if ((node->stats.st_mode & S_IXUSR) || (node->stats.st_mode & S_IXGRP) || (node->stats.st_mode & S_IXOTH)) {
|
||||
suf = '*';
|
||||
color = LS_EXE_COLOR;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
if (i_flag)
|
||||
ret += printf("%7ju ", (uintmax_t)node->stats.st_ino);
|
||||
|
||||
if (s_flag) {
|
||||
off_t size = 512 * node->stats.st_blocks;
|
||||
if (h_flag)
|
||||
ret += printf("%7s ", mu_humansize(size, 1024));
|
||||
|
||||
else
|
||||
ret += printf("%7jd ", size / 1024);
|
||||
}
|
||||
|
||||
if (l_flag) {
|
||||
printf("%s", mode);
|
||||
|
||||
struct passwd *pw = getpwuid(node->stats.st_uid);
|
||||
struct group *gr = getgrgid(node->stats.st_gid);
|
||||
if (pw == NULL || gr == NULL) {
|
||||
fprintf(stderr, "ls: print: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (h_flag)
|
||||
ret += printf(" %4ju %4s %6s %6s %s ", (uintmax_t)node->stats.st_nlink, pw->pw_name, gr->gr_name, mu_humansize(node->stats.st_size, 1024), get_date(node->stats.st_mtime));
|
||||
|
||||
else
|
||||
ret += printf(" %4ju %4s %6s %10ld %s ", (uintmax_t)node->stats.st_nlink, pw->pw_name, gr->gr_name, node->stats.st_size, get_date(node->stats.st_mtime));
|
||||
}
|
||||
|
||||
if (c_flag && p_flag)
|
||||
printf("%s", color);
|
||||
|
||||
printf("%s", node->name);
|
||||
ret += utf8_strlen(node->name);
|
||||
|
||||
if (c_flag && p_flag)
|
||||
printf("\033[0m");
|
||||
|
||||
if (F_flag)
|
||||
printf("%c", suf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int col_print(struct d_node **node, const size_t files, const struct winsize w) {
|
||||
/* Get max len */
|
||||
size_t maxlen = 0;
|
||||
for (size_t i = 0; i < files; i++) {
|
||||
size_t len = utf8_strlen(node[i]->name);
|
||||
if (len > maxlen)
|
||||
maxlen = len;
|
||||
}
|
||||
|
||||
/* Calc */
|
||||
maxlen += 3;
|
||||
if (i_flag)
|
||||
maxlen += 10;
|
||||
|
||||
if (s_flag)
|
||||
maxlen += 10;
|
||||
|
||||
size_t ncols = w.ws_col / maxlen;
|
||||
size_t nrows = files;
|
||||
if (ncols > 1) {
|
||||
nrows = files / ncols;
|
||||
if (nrows * ncols < files)
|
||||
nrows++;
|
||||
}
|
||||
|
||||
else
|
||||
ncols = 1;
|
||||
|
||||
int col = 0;
|
||||
int nexttab = 0;
|
||||
|
||||
/* Mc print */
|
||||
for (size_t i = 0; i < nrows; i++) {
|
||||
for (size_t j = 0; j < ncols; j++) {
|
||||
size_t index = j * nrows + i;
|
||||
if (index < files) {
|
||||
if (col > 0) {
|
||||
nexttab -= col;
|
||||
col += nexttab;
|
||||
for (int k = 0; k < nexttab; k++)
|
||||
putchar(' ');
|
||||
}
|
||||
|
||||
nexttab = col + (int)maxlen;
|
||||
int ret = print(node[index]);
|
||||
if (ret == -1)
|
||||
return 1;
|
||||
|
||||
col += ret;
|
||||
}
|
||||
}
|
||||
|
||||
putchar((nul_flag) ? '\0' : '\n');
|
||||
col = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int struct_print(struct d_node **dir, const size_t files, const struct winsize w) {
|
||||
int ret = 0;
|
||||
|
||||
/* pipe print */
|
||||
if (!p_flag || l_flag || O_flag) {
|
||||
for (size_t i = 0; i < files; i++) {
|
||||
if (print(dir[i]) == -1)
|
||||
ret = 1;
|
||||
|
||||
putchar((nul_flag) ? '\0' : '\n');
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
if (col_print(dir, files, w))
|
||||
ret = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Sort */
|
||||
int sortt(const void *p1, const void *p2) {
|
||||
return (*(struct d_node **)p2)->stats.st_mtime - (*(struct d_node **)p1)->stats.st_mtime;
|
||||
}
|
||||
|
||||
int sorts(const void *p1, const void *p2) {
|
||||
return (*(struct d_node **)p2)->stats.st_size - (*(struct d_node **)p1)->stats.st_size;
|
||||
}
|
||||
|
||||
int sortd(const void *p1, const void *p2) {
|
||||
return strcmp((*(struct d_node **)p1)->full_name, (*(struct d_node **)p2)->full_name);
|
||||
}
|
||||
|
||||
/* Ls */
|
||||
int ls_dir(const char *dir_name, const int label, const struct winsize w) {
|
||||
if (dir_name == NULL)
|
||||
return 0;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
size_t files = 0;
|
||||
off_t total_size = 0;
|
||||
struct d_node **dir = list(dir_name, &total_size, &files, &ret);
|
||||
|
||||
/* Title */
|
||||
if ((label || R_flag) && !d_flag)
|
||||
printf("\n%s:\n", dir_name);
|
||||
|
||||
if (l_flag) {
|
||||
if (h_flag)
|
||||
printf("total: %s\n", mu_humansize(total_size * 512, 1024));
|
||||
|
||||
else
|
||||
printf("total: %jd\n", (intmax_t)total_size / 2);
|
||||
}
|
||||
|
||||
if (dir == NULL)
|
||||
return 1;
|
||||
|
||||
qsort(dir, files, sizeof(struct d_node *), sorter);
|
||||
|
||||
if (struct_print(dir, files, w))
|
||||
ret = 1;
|
||||
|
||||
if (R_flag)
|
||||
for (size_t i = 0; i < files; i++)
|
||||
if (S_ISDIR(dir[i]->stats.st_mode) && strcmp(dir[i]->name, "..") && strcmp(dir[i]->name, "."))
|
||||
ls_dir(dir[i]->full_name, 1, w);
|
||||
|
||||
dfree(dir, files);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ls_files(int argc, char **argv, const struct winsize w) {
|
||||
size_t files = 0;
|
||||
struct d_node **file = malloc(sizeof(struct d_node *));
|
||||
if (file == NULL) {
|
||||
fprintf(stderr, "ls: malloc: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
struct stat sb;
|
||||
if (mu_get_lstat("ls", argv[i], &sb)) {
|
||||
ret = 1;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (S_ISDIR(sb.st_mode))
|
||||
continue;
|
||||
|
||||
struct d_node **tmp = realloc(file, sizeof(struct d_node *) * (files + 1));
|
||||
if (tmp == NULL) {
|
||||
dfree(file, files);
|
||||
return 1;
|
||||
}
|
||||
file = tmp;
|
||||
|
||||
file[files] = stat_file(argv[i], 1);
|
||||
if (file[files] == NULL) {
|
||||
dfree(file, files);
|
||||
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
files++;
|
||||
argv[i] = NULL;
|
||||
}
|
||||
|
||||
qsort(file, files, sizeof(struct d_node *), sorter);
|
||||
if (struct_print(file, files, w))
|
||||
ret = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "1alFcRdLhistS0")) != -1) {
|
||||
switch (opt) {
|
||||
case '1':
|
||||
O_flag = 1;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
a_flag = 1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
l_flag = 1;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
F_flag = 1;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
c_flag = 1;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
d_flag = 0;
|
||||
R_flag = 1;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
R_flag = 0;
|
||||
d_flag = 1;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
L_flag = 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
h_flag = 1;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
i_flag = 1;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
s_flag = 1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
sorter = sortt;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
sorter = sorts;
|
||||
break;
|
||||
|
||||
case '0':
|
||||
nul_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ls [1alFcRdLhistS0] [dir1 file2...]\n\t-a Show hidden files\n\t-l Use a long listing format\n\t-F Append indicator to names\n\t-c Color mode\n\t-R Recursive\n\t-1 One column\n\t-d Print only dir names\n\t-L Follow symlinks\n\t-h Sizes in human readable format\n\t-i Listen inodes\n\t-t Sort by mtime\n\t-S Sort by size\n\t-s Print file size\n\t-0 End line with \\0\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
struct winsize w;
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||
|
||||
/* Check if programm piped, 1 - false, 0 - true */
|
||||
p_flag = isatty(STDOUT_FILENO);
|
||||
|
||||
int ret = 0;
|
||||
if (ls_files(argc, argv, w))
|
||||
ret = 1;
|
||||
|
||||
if (argc == 0) {
|
||||
if (ls_dir(".", 0, w))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
else if (argc == 1) {
|
||||
if (ls_dir(argv[0], 0, w))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
else {
|
||||
for (int i = 0; i < argc; i++)
|
||||
if (ls_dir(argv[i], 1, w))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
3
src/coreutils/mkdir/build.sh
Executable file
3
src/coreutils/mkdir/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
85
src/coreutils/mkdir/mkdir.c
Normal file
85
src/coreutils/mkdir/mkdir.c
Normal file
@ -0,0 +1,85 @@
|
||||
#include <sys/stat.h>
|
||||
#include <libgen.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "parse_mode.h"
|
||||
|
||||
char v_flag;
|
||||
char p_flag;
|
||||
mode_t mode = 0777;
|
||||
|
||||
int do_mkdir(const char *path) {
|
||||
if (mkdir(path, mode)) {
|
||||
if (p_flag)
|
||||
return 0;
|
||||
|
||||
fprintf(stderr, "mkdir: %s: %s\n", path, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
else if (v_flag)
|
||||
printf("mkdir: %s created with mode %u\n", path, mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_parents(const char *path) {
|
||||
if (path[0] == '.' || path[0] == '/')
|
||||
return 0;
|
||||
|
||||
char *path2 = strdup(path);
|
||||
if (!path2) {
|
||||
fprintf(stderr, "mkdir: %s: %s\n", path, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *par = dirname(path2);
|
||||
do_parents(par);
|
||||
int ret = do_mkdir(path2);
|
||||
|
||||
free(path2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "pm:v")) != -1) {
|
||||
switch (opt) {
|
||||
case 'p':
|
||||
p_flag = 1;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
mode = mu_parse_mode(optarg, 0);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
v_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("mkdir [pmv] [dst1 dst2...]\n\t-p Make parent dir\n\t-m MODE Mode\n\t-v Verbose\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (p_flag) {
|
||||
if (do_parents(argv[i]))
|
||||
return 1;
|
||||
}
|
||||
|
||||
else {
|
||||
if (do_mkdir(argv[i]))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
3
src/coreutils/mknod/build.sh
Executable file
3
src/coreutils/mknod/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
81
src/coreutils/mknod/mknod.c
Normal file
81
src/coreutils/mknod/mknod.c
Normal file
@ -0,0 +1,81 @@
|
||||
#ifdef __linux__
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include "parse_mode.h"
|
||||
|
||||
long parse_long(const char *str) {
|
||||
char *ptr = NULL;
|
||||
long value = strtol(str, &ptr, 10);
|
||||
|
||||
if (*ptr) {
|
||||
fprintf(stderr, "mknod: not a number: %s\n", str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
else if (value < 0) {
|
||||
fprintf(stderr, "mknod: number is negative: %s\n", str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
mode_t mode = 0666;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "m:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'm':
|
||||
mode = mu_parse_mode(optarg, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("mknod [m] [NAME] [TYPE] [MAJOR MINOR]\n\t-m MODE\n\n");
|
||||
printf("Types:\n\tb - block device\n\tc or u - character device\n\tp - named pipe/fifo (MAJOR MINOR must be omitted)\n\ts - socket\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
if (argc <= 1) {
|
||||
fprintf(stderr, "mknod: missing operand\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
dev_t dev = 0;
|
||||
if (argc == 4)
|
||||
dev = makedev(parse_long(argv[2]), parse_long(argv[3]));
|
||||
|
||||
if (!strncmp("b", argv[1], 1))
|
||||
mode |= S_IFBLK;
|
||||
|
||||
else if (!strncmp("c", argv[1], 1) || !strncmp("u", argv[1], 1))
|
||||
mode |= S_IFCHR;
|
||||
|
||||
else if (!strncmp("p", argv[1], 1))
|
||||
mode |= S_IFIFO;
|
||||
|
||||
else if (!strncmp("s", argv[1], 1))
|
||||
mode |= S_IFSOCK;
|
||||
|
||||
else {
|
||||
fprintf(stderr, "mknod: unknow file type\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mknod(argv[0], mode, dev) < 0) {
|
||||
fprintf(stderr, "mknod: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
3
src/coreutils/mktemp/build.sh
Executable file
3
src/coreutils/mktemp/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
98
src/coreutils/mktemp/mktemp.c
Normal file
98
src/coreutils/mktemp/mktemp.c
Normal file
@ -0,0 +1,98 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "make_path.h"
|
||||
|
||||
int make_temp_dir(char *tmp) {
|
||||
if (!mkdtemp(tmp)) {
|
||||
if (errno == EINVAL)
|
||||
fprintf(stderr, "mktemp: template does not end in exactly 'XXXXX': %s\n", tmp);
|
||||
|
||||
else
|
||||
fprintf(stderr, "mktemp: %s\n", strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_suffix(const char *str) {
|
||||
size_t len = strlen(str);
|
||||
for (size_t i = len - 1; i > 0; i--)
|
||||
if (str[i] == 'X')
|
||||
return len - i - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int make_temp_file(char *tmp) {
|
||||
if (!strstr(tmp, "XXXXXX")) {
|
||||
fprintf(stderr, "mktemp: too few X's in template: %s\n", tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fd = mkstemps(tmp, get_suffix(tmp));
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "mktemp: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
unsigned int d_flag = 0;
|
||||
char *path = NULL;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "dp:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
d_flag = 1;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
path = optarg;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("mktemp [dp] [file]\n\t-d Dir\n\t-p Base dir\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc == 0 && path == NULL) {
|
||||
path = getenv("TMPDIR");
|
||||
if (!path || path[0] == '\0')
|
||||
path = "/tmp/";
|
||||
}
|
||||
|
||||
char *x = mu_make_path("mktemp", path, (argc == 0) ? "tmp.XXXXXX" : argv[0]);
|
||||
if (x == NULL)
|
||||
return 1;
|
||||
|
||||
if (d_flag) {
|
||||
if (make_temp_dir(x)) {
|
||||
free(x);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
if (make_temp_file(x)) {
|
||||
free(x);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
puts(x);
|
||||
free(x);
|
||||
return 0;
|
||||
}
|
3
src/coreutils/mv/build.sh
Executable file
3
src/coreutils/mv/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
62
src/coreutils/mv/mv.c
Normal file
62
src/coreutils/mv/mv.c
Normal file
@ -0,0 +1,62 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "make_path.h"
|
||||
char *f_flag = "mv";
|
||||
|
||||
int move(const char *src, const char *dst) {
|
||||
char *copy = strdup(src);
|
||||
if (!copy)
|
||||
return 1;
|
||||
|
||||
char *new_path = mu_make_path(f_flag, dst, basename(copy));
|
||||
if (new_path == NULL) {
|
||||
free(copy);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
if (rename(src, new_path) < 0)
|
||||
ret = 1;
|
||||
|
||||
free(new_path);
|
||||
free(copy);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "f")) != -1) {
|
||||
switch (opt) {
|
||||
case 'f':
|
||||
f_flag = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("mv [f] [src1 src2...] [dst]\n\t-f Force\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
/* Move code */
|
||||
for (int i = 0; i < argc - 1; i++) {
|
||||
if (move(argv[i], argv[argc - 1])) {
|
||||
if (rename(argv[i], argv[argc - 1]) < 0) {
|
||||
if (f_flag)
|
||||
fprintf(stderr, "mv: %s %s\n", argv[i], strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
3
src/coreutils/nice/build.sh
Executable file
3
src/coreutils/nice/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
43
src/coreutils/nice/nice.c
Normal file
43
src/coreutils/nice/nice.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int oldp = getpriority(PRIO_PROCESS, 0);
|
||||
int adj = 10;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "n:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'n':
|
||||
adj = atoi(optarg);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("nice [n] [cmd] [arg1] [arg2]\n\t-n N Add N to the niceness\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc == 0) {
|
||||
printf("%d\n", oldp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (setpriority(PRIO_PROCESS, 0, oldp + adj) < 0) {
|
||||
fprintf(stderr, "nice: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
execvp(argv[0], argv);
|
||||
fprintf(stderr, "nice: %s: %s\n", argv[0], strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
3
src/coreutils/nohup/build.sh
Executable file
3
src/coreutils/nohup/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
42
src/coreutils/nohup/nohup.c
Normal file
42
src/coreutils/nohup/nohup.c
Normal file
@ -0,0 +1,42 @@
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include "unused.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
printf("nohup: missing operand\nnohup [cmd]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fork() != 0)
|
||||
return 0;
|
||||
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
|
||||
if (isatty(STDOUT_FILENO)) {
|
||||
int fd = open("nohup.out", O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "nohup: nohup.out: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (dup2(fd, STDOUT_FILENO) < 0)
|
||||
fprintf(stderr, "nohup: %s\n", strerror(errno));
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
if (isatty(STDERR_FILENO))
|
||||
if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0)
|
||||
fprintf(stderr, "nohup: %s\n", strerror(errno));
|
||||
|
||||
argv++;
|
||||
execvp(argv[0], argv);
|
||||
fprintf(stderr, "nohup: %s: %s\n", argv[0], strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
3
src/coreutils/nproc/build.sh
Executable file
3
src/coreutils/nproc/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
11
src/coreutils/nproc/nproc.c
Normal file
11
src/coreutils/nproc/nproc.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(void) {
|
||||
long count = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (count <= 0)
|
||||
count = 1;
|
||||
|
||||
printf("%ld\n", count);
|
||||
return 0;
|
||||
}
|
3
src/coreutils/printenv/build.sh
Executable file
3
src/coreutils/printenv/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
40
src/coreutils/printenv/printenv.c
Normal file
40
src/coreutils/printenv/printenv.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int printvars(int len, char **names) {
|
||||
int ret = 0;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
char *val = getenv(names[i]);
|
||||
if (!val) {
|
||||
ret = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("%s\n", val);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, const char **envp) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "0")) != -1) {
|
||||
printf("printenv [var1 var2...]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc == 0)
|
||||
while (*envp)
|
||||
printf("%s\n", *envp++);
|
||||
|
||||
else
|
||||
return printvars(argc, argv);
|
||||
|
||||
return 0;
|
||||
}
|
3
src/coreutils/pwd/build.sh
Executable file
3
src/coreutils/pwd/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
19
src/coreutils/pwd/pwd.c
Normal file
19
src/coreutils/pwd/pwd.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main(void) {
|
||||
char cwd[PATH_MAX];
|
||||
|
||||
if (getcwd(cwd, sizeof(cwd)))
|
||||
puts(cwd);
|
||||
|
||||
else {
|
||||
fprintf(stderr, "pwd: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
3
src/coreutils/readlink/build.sh
Executable file
3
src/coreutils/readlink/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
48
src/coreutils/readlink/readlink.c
Normal file
48
src/coreutils/readlink/readlink.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char n_flag = 0;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "n")) != -1) {
|
||||
switch (opt) {
|
||||
case 'n':
|
||||
n_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("readlink [n] [file1 file2...]\n\t-n Don't add newline\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
char path[PATH_MAX + 1];
|
||||
ssize_t r = readlink(argv[i], path, sizeof(path));
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "readlink: %s: %s\n", argv[i], strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (r > (ssize_t)sizeof(path)) {
|
||||
fprintf(stderr, "readlink: %s: path too long\n", argv[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (n_flag)
|
||||
fputs(path, stdout);
|
||||
|
||||
else
|
||||
puts(path);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
3
src/coreutils/renice/build.sh
Executable file
3
src/coreutils/renice/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
73
src/coreutils/renice/renice.c
Normal file
73
src/coreutils/renice/renice.c
Normal file
@ -0,0 +1,73 @@
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
int renice(int which, int who, int adj) {
|
||||
adj += getpriority(which, who);
|
||||
|
||||
if (setpriority(which, who, adj)) {
|
||||
fprintf(stderr, "renice: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int adj = 10;
|
||||
int which = PRIO_PROCESS;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "n:gup")) != -1) {
|
||||
switch (opt) {
|
||||
case 'n':
|
||||
adj = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
which = PRIO_PGRP;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
which = PRIO_USER;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
which = PRIO_PROCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("renice [ngup] [id1 id2...]\n\t-n N Add N to the niceness\n\t-g Process group ids\n\t-u Process user names\n\t-p Process ids\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
int who = 0;
|
||||
int ret = 0;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (which == PRIO_USER) {
|
||||
struct passwd *pw = getpwnam(argv[i]);
|
||||
if (pw == 0) {
|
||||
fprintf(stderr, "renice: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
who = pw->pw_uid;
|
||||
}
|
||||
|
||||
else
|
||||
who = atoi(argv[i]);
|
||||
|
||||
if (renice(which, who, adj))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
3
src/coreutils/rm/build.sh
Executable file
3
src/coreutils/rm/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
112
src/coreutils/rm/rm.c
Normal file
112
src/coreutils/rm/rm.c
Normal file
@ -0,0 +1,112 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include "make_path.h"
|
||||
#include "get_stat.h"
|
||||
#include "recurse.h"
|
||||
#include "unused.h"
|
||||
|
||||
char *f_flag = "rm";
|
||||
char r_flag;
|
||||
char v_flag;
|
||||
|
||||
int verbose(const char *path) {
|
||||
if (v_flag) {
|
||||
fprintf(stderr, "rm: remove %s? [y/n] ", path);
|
||||
fflush(stderr);
|
||||
|
||||
int c = 0;
|
||||
int key = 0;
|
||||
|
||||
while ((c = fgetc(stdin)) != EOF && c != '\n') {
|
||||
if (c == 'y')
|
||||
key = 1;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void handle_error(const char *path) {
|
||||
if (f_flag)
|
||||
fprintf(stderr, "rm: %s: %s\n", path, strerror(errno));
|
||||
}
|
||||
|
||||
int rm(const char *path, void *p) {
|
||||
UNUSED(p);
|
||||
|
||||
if (verbose(path) && remove(path) < 0) {
|
||||
handle_error(path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rmd(const char *path, void *p) {
|
||||
UNUSED(p);
|
||||
|
||||
if (verbose(path) && rmdir(path) < 0) {
|
||||
handle_error(path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "frRi")) != -1) {
|
||||
switch (opt) {
|
||||
case 'f':
|
||||
f_flag = NULL;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
r_flag = 1;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
v_flag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("rm [rif] [file1 file2...]\n\t-f Force\n\t-r Recursive\n\t-i Print prompt before remove\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc == 0) {
|
||||
fprintf(stderr, "rm: missing operand\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (!strcmp(argv[i], ".") || !strcmp(argv[i], "..")){
|
||||
printf("rm: refusing to remove '.' or '..' directory\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (r_flag) {
|
||||
if (mu_recurse(f_flag, 1, argv[i], NULL, rm, rmd))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
else
|
||||
if (rm(argv[i], NULL))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
3
src/coreutils/seq/build.sh
Executable file
3
src/coreutils/seq/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
58
src/coreutils/seq/seq.c
Normal file
58
src/coreutils/seq/seq.c
Normal file
@ -0,0 +1,58 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
double parse_double(const char *str) {
|
||||
char *ptr;
|
||||
|
||||
double res = strtod(str, &ptr);
|
||||
if (*ptr) {
|
||||
fprintf(stderr, "seq: %s: cant parse\n", ptr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
double start = 1;
|
||||
double last = 0;
|
||||
double n = 1;
|
||||
|
||||
argv++;
|
||||
argc--;
|
||||
|
||||
switch (argc) {
|
||||
case 1:
|
||||
last = parse_double(argv[0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
start = parse_double(argv[0]);
|
||||
last = parse_double(argv[1]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
n = parse_double(argv[1]);
|
||||
start = parse_double(argv[0]);
|
||||
last = parse_double(argv[2]);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "seq: missing operands\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (start <= last && n >= 0) {
|
||||
for (double i = start; i <= last; i += n)
|
||||
printf("%g\n", i);
|
||||
}
|
||||
|
||||
else if (n <= 0)
|
||||
for (double i = start; i >= last; i += n)
|
||||
printf("%g\n", i);
|
||||
|
||||
return 0;
|
||||
}
|
3
src/coreutils/setsid/build.sh
Executable file
3
src/coreutils/setsid/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
21
src/coreutils/setsid/setsid.c
Normal file
21
src/coreutils/setsid/setsid.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include "unused.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
UNUSED(argc);
|
||||
|
||||
if (argv[1] == NULL) {
|
||||
printf("setsid [cmd] [arg1 arg2...]\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fork() != 0)
|
||||
return 0;
|
||||
|
||||
setsid();
|
||||
execvp(argv[1], argv + 1);
|
||||
}
|
3
src/coreutils/shred/build.sh
Executable file
3
src/coreutils/shred/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
113
src/coreutils/shred/shred.c
Normal file
113
src/coreutils/shred/shred.c
Normal file
@ -0,0 +1,113 @@
|
||||
#define _SHRED_C
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include "config.h"
|
||||
|
||||
char f_flag;
|
||||
char u_flag;
|
||||
char z_flag;
|
||||
int n_loops = 3;
|
||||
|
||||
int shred(int rand_fd, int fd) {
|
||||
|
||||
/* Get size */
|
||||
off_t size = lseek(fd, 0, SEEK_END);
|
||||
if (size <= 0)
|
||||
return 1;
|
||||
|
||||
void *buf = mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (buf == MAP_FAILED) {
|
||||
fprintf(stderr, "shred: mmap: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (char n = 0; n < n_loops; n++) {
|
||||
if (read(rand_fd, buf, size) == 0)
|
||||
fprintf(stderr, "shred: %s", strerror(errno));
|
||||
|
||||
fsync(fd);
|
||||
}
|
||||
|
||||
if (z_flag)
|
||||
memset(buf, 0, size);
|
||||
|
||||
if (munmap(buf, size)) {
|
||||
fprintf(stderr, "shred: munmap: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "fuzn:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'f':
|
||||
f_flag = 1;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
u_flag = 1;
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
z_flag = 1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
n_loops = atoi(optarg);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("shred [fuzn] [file1 file2...]\n\t-n N Overwrite N times, default 3\n\t-z Final overwrite with zeros\n\t-u Remove file\n\t-f Chmod to ensure writability\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
if (argc == 0) {
|
||||
fprintf(stderr, "shred: missing operand\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rand_fd = open(RAND_SOURCE, O_RDONLY);
|
||||
if (rand_fd < 0) {
|
||||
fprintf(stderr, "shred: %s: %s\n", RAND_SOURCE, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
int fd = open(argv[i], O_RDWR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
shred(rand_fd, fd);
|
||||
fsync(fd);
|
||||
close(fd);
|
||||
|
||||
if (f_flag) {
|
||||
if (chmod(argv[i], 0) < 0)
|
||||
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
|
||||
}
|
||||
|
||||
if (u_flag) {
|
||||
if (unlink(argv[i]) < 0)
|
||||
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
close(rand_fd);
|
||||
return 0;
|
||||
}
|
3
src/coreutils/sleep/build.sh
Executable file
3
src/coreutils/sleep/build.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
29
src/coreutils/sleep/sleep.c
Normal file
29
src/coreutils/sleep/sleep.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "duration.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "")) != -1 || argc == 1) {
|
||||
printf("sleep [num[SUFFIX]] or [inf Infinity]\nSUFFIXES:\n\tm - minute\n\th - hour\n\td - days\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (!strncasecmp(argv[0], "inf", 3))
|
||||
while (1)
|
||||
sleep(INT_MAX);
|
||||
|
||||
unsigned long long usec = 0;
|
||||
for (int i = 0; i < argc; i++)
|
||||
usec += mu_parse_duration(argv[i]);
|
||||
|
||||
usleep(usec);
|
||||
return 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user