⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buildin.c

📁 Linux下写一个命令解释程序,实现了基本的功能.
💻 C
字号:
#include "buildin.h"
#include "common.h"
#include <dirent.h>  /* dir */
#include <time.h>    /* time */
#include <ftw.h>
#include <termios.h>

static struct termios keypress_settings;
static struct termios echo_settings;

void set_keypress(void)
{
  struct termios new_settings;
  tcgetattr(0,&keypress_settings);

  new_settings = keypress_settings;

  /* Disable canonical mode, and set buffer size to 1 byte */
  new_settings.c_lflag &= (~ICANON);
  new_settings.c_cc[VTIME] = 0;
  new_settings.c_cc[VMIN] = 1;

  tcsetattr(0,TCSANOW,&new_settings);
  return;
}

void reset_keypress(void)
{
  tcsetattr(0,TCSANOW,&keypress_settings);
  return;
}
 
void echo_off(void)
{
  struct termios new_settings;
  tcgetattr(0,&echo_settings);
  new_settings = echo_settings;
  new_settings.c_lflag &= (~ECHO);
  tcsetattr(0,TCSANOW,&new_settings);
  return;
}

void echo_on(void)
{
  tcsetattr(0,TCSANOW,&echo_settings);
  return;
}

int __cd(const char *path_name)
{
  if ( chdir(path_name) ) {
    printf("failed to change current directory: %s\n",
           strerror(errno));
    return 1;
  }
  return 0;
}

char * __pwd(void)
{
  int len = INCREMENT_LEN * 10;
  char *buf = malloc(len);

  while (!getcwd(buf, len)) {
    len += INCREMENT_LEN * 10;
    buf = realloc(buf, len);
  }
  return buf;
}

int __dir(const char *path_name)
{
  DIR   *dfd;
  struct dirent *dp;

  if( ( dfd = opendir(path_name) ) == NULL ) {
    fprintf(stderr, "Can't open %s: %s\n", path_name, strerror(errno));
    return 1;
  }
  while( ( dp = readdir(dfd) ) != NULL ) {
    if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
      continue;
    printf("%s\n",dp->d_name);
  }
  closedir(dfd);
  return 0;
}

char * __time(const char *fmt)
{
  time_t caltime;
  struct tm *tim;
  char *line = malloc(sizeof(char)*MAX_COMMAND_LEN);

  if ((caltime=time(NULL))==-1)
    perror("time()");
  if ((tim=localtime(&caltime))==NULL)
    perror("localtime()");
  if (strftime(line,MAX_COMMAND_LEN,fmt,tim)==0)
    perror("strftime()");
  return line;
}

int __ren(const char *from, const char *to)
{
  if (rename(from, to))
    fprintf(stderr, "unable to rename %s to %s: %s\n",
            from, to, strerror(errno));
  return 0;
}

int __md(const char *dir_name)
{
  if (mkdir(dir_name, 0755))
    fprintf(stderr, "unable to create directory %s: %s\n",
            dir_name, strerror(errno));

  return 0;
}

/* find function */
 
static int counter;

static int fn(const char *file, const struct stat *sb, int flag)
{
  char *p;
  char *filename;
  p = getenv("tmp_file");
  filename = strrchr(file,'/');
  filename++;
  if( strcmp(filename, p)==0 ) {
    printf("%s\n",file);
    counter++;
  }
  return 0;
}

int __find(const char *path_name, const char *file_name)
{
  counter = 0;
  setenv("tmp_file", file_name, 1); /* override existed filename*/
  ftw(path_name, fn, 0);  
  unsetenv("tmp_file");
  if (counter)
    printf("%s: total found %d\n", file_name, counter);
  return 0;
}

/* more function */

int __more(int fd)
{
  int i, n;
  int col = 0;
  int row = 0;
  struct winsize wsize;
  char buffer[MAX_COMMAND_LEN];
  char waitchar;
  
  set_keypress();
  echo_off();
  ioctl(STDIN_FILENO, TIOCGWINSZ, (char *) &wsize);
  
  while ((n = read(fd, buffer, MAX_COMMAND_LEN))>0) {
    for (i = 0; i < n; i++) {
      if (buffer[i] == '\n')
        row++, col = 0;
      else
        col++;
            
      if (col == wsize.ws_col)
        col = 0, row++;
                     
      if(row == (wsize.ws_row-1)) {
        printf("\n----- Press any key to continue -----");
        waitchar = getc(stdin);
        switch (waitchar) {
        case 'q':
        case 'Q':
          goto EXIT;
        default:
          col = 0, row = 0;
        }
      }
      printf("%c", buffer[i]);
    }
  }
 EXIT:  
  echo_on();
  reset_keypress();
  printf("\n===========================\n");
  return 0;
}

int __del(const char *file_name)
{
  if (access(file_name, F_OK) < 0) {
    fprintf(stderr, "%s: %s\n", file_name, strerror(errno));
    return 1;
  }
  if (remove(file_name) == -1) {
    fprintf(stderr, "%s: %s\n", file_name, strerror(errno));
    return 1;
  }
  return 0;
}

static void copy_file(const char *source, const char *dest, int mode)
{
  int fd1,fd2,n; 
  char buf[BUFF_SIZE];
  
  fd1 = open(source, O_RDONLY);  
  fd2 = creat(dest, mode);
  while((n = read(fd1,buf, BUFF_SIZE)) > 0) {
    write(fd2,buf,n);
  }
  close(fd1);
  close(fd2);
}

/* The main copy function(recursive). 
 * If dest has existed, a prompt will be printed.
 * If source is regular file, call copy_file.
 * If source is directory, call mkdir.
 */ 
static void rcopy(const char *source, const char *dest)
{
  DIR      *dfd;
  struct dirent *dp;
  struct stat buf;
  char *cat_source;
  char *cat_dest;
  char request;
 
  char resolved_source_path[1024],resolved_dest_path[1024];

  if (lstat(source, &buf)<0) {
    fprintf(stderr, "%s: lstat fail!!\n", source);
    return;
  }
  if(S_ISREG(buf.st_mode)) {  
    if (!access(dest, F_OK)) {
      printf("\nfile: %s: already exist", dest);
      do {
        printf("\n[c]ontinue or [s]kip? ");
        scanf("%c", &request);
        if (request == 's' || request == 'S')
          return;
        else if (request == 'c' || request == 'C')
          break;
      } while (1);
    } 
    copy_file(source, dest, buf.st_mode);
  }
  else if(S_ISDIR(buf.st_mode)) { 
    if (!access(dest, F_OK)) {
      printf("\ndirectory: %s: already exist", dest);
      do {
        printf("\n[c]ontinue or [s]kip? ");
        scanf("%c", &request);
        if (request == 's' || request == 'S')
          return;
        else if (request == 'c' || request == 'C')
          break;
      } while (1);
    }    
    mkdir(dest, buf.st_mode);
    realpath(dest, resolved_dest_path);
    realpath(source, resolved_source_path);
    cat_dest = resolved_dest_path + strlen(resolved_dest_path);
    cat_source = resolved_source_path + strlen(resolved_source_path);
 
    if((dfd = opendir(resolved_source_path))==NULL) {
      fprintf(stderr, "can't open %s\n",source);
      return;
    }
    *cat_dest = *cat_source = '/';
    cat_dest++, cat_source++;
 
    while((dp = readdir(dfd))!=NULL) {
      if (strcmp(dp->d_name, ".") == 0 ||
          strcmp(dp->d_name, "..") == 0)
        continue;
      /* recursive */
      strcpy(cat_dest, dp->d_name);
      strcpy(cat_source, dp->d_name);
      rcopy(resolved_source_path, resolved_dest_path);
    }

  }
}

void __copy(const char *dest, const char *source)
{
  set_keypress();
  rcopy(source, dest);
  reset_keypress();
  printf("\ncopy %s to %s finished!\n", source, dest);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -