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

📄 tools.c

📁 EmuNation的最初开放版本源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * tools.c: Various tools * * See the main source file 'vdr.c' for copyright information and * how to reach the author. * * $Id: tools.c 1.82 2004/11/21 14:36:34 kls Exp $ */#include "tools.h"#include <ctype.h>#include <dirent.h>#include <errno.h>#include <stdlib.h>#include <sys/types.h>#include <sys/timeb.h>//#include <sys/vfs.h>#include <time.h>#include <unistd.h>//#include "i18n.h"int SysLogLevel = 3;void syslog (int log_t,...){     //Do nothing porting is too bad.}template<class T> T min ( T a , T b ) {   return a <= b ? a : b; }template<class T> inline T max(T a, T b) { return a >= b ? a : b; }template<class T> inline int sgn(T a) { return a < 0 ? -1 : a > 0 ? 1 : 0; }template<class T> inline void swap(T &a, T &b) { T t = a; a = b; b = t; }int BCD2INT(int x){  return ((1000000 * BCDCHARTOINT((x >> 24) & 0xFF)) +            (10000 * BCDCHARTOINT((x >> 16) & 0xFF)) +              (100 * BCDCHARTOINT((x >>  8) & 0xFF)) +                     BCDCHARTOINT( x        & 0xFF));}/*ssize_t safe_read(int filedes, void *buffer, size_t size){  for (;;) {      ssize_t p = read(filedes, buffer, size);      if (p < 0 && errno == EINTR) {         dsyslog("EINTR while reading from file handle %d - retrying", filedes);         continue;         }      return p;      }}ssize_t safe_write(int filedes, const void *buffer, size_t size){  ssize_t p = 0;  ssize_t written = size;  const unsigned char *ptr = (const unsigned char *)buffer;  while (size > 0) {        p = write(filedes, ptr, size);        if (p < 0) {           if (errno == EINTR) {              dsyslog("EINTR while writing to file handle %d - retrying", filedes);              continue;              }           break;           }        ptr  += p;        size -= p;        }  return p < 0 ? p : written;}void writechar(int filedes, char c){  safe_write(filedes, &c, sizeof(c));}*/char *readline(FILE *f){  static char buffer[MAXPARSEBUFFER];  if (fgets(buffer, sizeof(buffer), f) > 0) {     int l = strlen(buffer) - 1;     if (l >= 0 && buffer[l] == '\n')        buffer[l] = 0;     return buffer;     }  return NULL;}char *strcpyrealloc(char *dest, const char *src){  if (src) {     int l = max(dest ? strlen(dest) : 0, strlen(src)) + 1; // don't let the block get smaller!     dest = (char *)realloc(dest, l);     if (dest)        strcpy(dest, src);     else        printf("ERROR: out of memory\n");     }  else {     free(dest);     dest = NULL;     }  return dest;}char *strn0cpy(char *dest, const char *src, size_t n){  char *s = dest;  for ( ; --n && (*dest = *src) != 0; dest++, src++) ;  *dest = 0;  return s;}char *strreplace(char *s, char c1, char c2){  char *p = s;  while (p && *p) {        if (*p == c1)           *p = c2;        p++;        }  return s;}char *strreplace(char *s, const char *s1, const char *s2){  char *p = strstr(s, s1);  if (p) {     int of = p - s;     int l  = strlen(s);     int l1 = strlen(s1);     int l2 = strlen(s2);     if (l2 > l1)        s = (char *)realloc(s, strlen(s) + l2 - l1 + 1);     if (l2 != l1)        memmove(s + of + l2, s + of + l1, l - of - l1 + 1);     strncpy(s + of, s2, l2);     }  return s;}char *skipspace(const char *s){  while (*s && isspace(*s))        s++;  return (char *)s;}char *stripspace(char *s){  if (s && *s) {     for (char *p = s + strlen(s) - 1; p >= s; p--) {         if (!isspace(*p))            break;         *p = 0;         }     }  return s;}char *compactspace(char *s){  if (s && *s) {     char *t = stripspace(skipspace(s));     char *p = t;     while (p && *p) {           char *q = skipspace(p);           if (q - p > 1)              memmove(p + 1, q, strlen(q) + 1);           p++;           }     if (t != s)        memmove(s, t, strlen(t) + 1);     }  return s;}const char *strescape(const char *s, const char *chars){  static char *buffer = NULL;  const char *p = s;  char *t = NULL;  while (*p) {        if (strchr(chars, *p)) {           if (!t) {              buffer = (char *)realloc(buffer, 2 * strlen(s) + 1);              t = buffer + (p - s);              s = strcpy(buffer, s);              }           *t++ = '\\';           }        if (t)           *t++ = *p;        p++;        }  if (t)     *t = 0;  return s;}bool startswith(const char *s, const char *p){  while (*p) {        if (*p++ != *s++)           return false;        }  return true;}bool endswith(const char *s, const char *p){  const char *se = s + strlen(s) - 1;  const char *pe = p + strlen(p) - 1;  while (pe >= p) {        if (*pe-- != *se-- || (se < s && pe >= p))           return false;        }  return true;}bool isempty(const char *s){  return !(s && *skipspace(s));}int numdigits(int n){  char buf[16];  snprintf(buf, sizeof(buf), "%d", n);  return strlen(buf);}#include <windows.h>int time_ms(void){    static time_t t0 = 0;  #ifdef X11  struct timeval t;  if (gettimeofday(&t, NULL) == 0) {     if (t0 == 0)        t0 = t.tv_sec; // this avoids an overflow (we only work with deltas)     return (t.tv_sec - t0) * 1000 + t.tv_usec / 1000;  }  #else  SYSTEMTIME t;  GetSystemTime(&t);  if(t0==0)    t0 = t.wSecond;  return (t.wSecond - t0) * 1000 + t.wMilliseconds / 1000;  #endif  return 0;}/*void delay_ms(int ms){  int t0 = time_ms();  while (time_ms() - t0 < ms)        ;}*/bool isnumber(const char *s){  if (!*s)     return false;  while (*s) {        if (!isdigit(*s))           return false;        s++;        }  return true;}const char *itoa(int n){  static char buf[16];  snprintf(buf, sizeof(buf), "%d", n);  return buf;}const char *AddDirectory(const char *DirName, const char *FileName){  static char *buf = NULL;  free(buf);  buf=new char[256];  sprintf(buf, "%s\\%s", DirName && *DirName ? DirName : ".", FileName);  return buf;}/*int FreeDiskSpaceMB(const char *Directory, int *UsedMB){  if (UsedMB)     *UsedMB = 0;  int Free = 0;  struct statfs statFs;  if (statfs(Directory, &statFs) == 0) {     double blocksPerMeg = 1024.0 * 1024.0 / statFs.f_bsize;     if (UsedMB)        *UsedMB = int((statFs.f_blocks - statFs.f_bfree) / blocksPerMeg);     Free = int(statFs.f_bavail / blocksPerMeg);     }  else     LOG_ERROR_STR(Directory);  return Free;}bool DirectoryOk(const char *DirName, bool LogErrors){  struct stat ds;  if (stat(DirName, &ds) == 0) {     if (S_ISDIR(ds.st_mode)) {        if (access(DirName, R_OK | W_OK | X_OK) == 0)           return true;        else if (LogErrors)           esyslog("ERROR: can't access %s", DirName);        }     else if (LogErrors)        esyslog("ERROR: %s is not a directory", DirName);     }  else if (LogErrors)     LOG_ERROR_STR(DirName);  return false;}bool MakeDirs(const char *FileName, bool IsDirectory){  bool result = true;  char *s = strdup(FileName);  char *p = s;  if (*p == '/')     p++;  while ((p = strchr(p, '/')) != NULL || IsDirectory) {        if (p)           *p = 0;        struct stat fs;        if (stat(s, &fs) != 0 || !S_ISDIR(fs.st_mode)) {           dsyslog("creating directory %s", s);           if (mkdir(s, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1) {              LOG_ERROR_STR(s);              result = false;              break;              }           }        if (p)           *p++ = '/';        else           break;        }  free(s);  return result;}bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks){  struct stat st;  if (stat(FileName, &st) == 0) {     if (S_ISDIR(st.st_mode)) {        DIR *d = opendir(FileName);        if (d) {           struct dirent *e;           while ((e = readdir(d)) != NULL) {                 if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {                    char *buffer;                    asprintf(&buffer, "%s/%s", FileName, e->d_name);                    if (FollowSymlinks) {                       int size = strlen(buffer) * 2; // should be large enough                       char *l = MALLOC(char, size);                       int n = readlink(buffer, l, size);                       if (n < 0) {                          if (errno != EINVAL)                             LOG_ERROR_STR(buffer);                          }                       else if (n < size) {                          l[n] = 0;                          dsyslog("removing %s", l);                          if (remove(l) < 0)                             LOG_ERROR_STR(l);                          }                       else                          esyslog("ERROR: symlink name length (%d) exceeded anticipated buffer size (%d)", n, size);                       free(l);                       }                    dsyslog("removing %s", buffer);                    if (remove(buffer) < 0)                       LOG_ERROR_STR(buffer);                    free(buffer);                    }                 }           closedir(d);           }        else {           LOG_ERROR_STR(FileName);           return false;           }        }     dsyslog("removing %s", FileName);     if (remove(FileName) < 0) {        LOG_ERROR_STR(FileName);        return false;        }     }  else if (errno != ENOENT) {     LOG_ERROR_STR(FileName);     return false;     }  return true;}bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis){  DIR *d = opendir(DirName);  if (d) {     bool empty = true;     struct dirent *e;     while ((e = readdir(d)) != NULL) {           if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..") && strcmp(e->d_name, "lost+found")) {              char *buffer;              asprintf(&buffer, "%s/%s", DirName, e->d_name);              struct stat st;              if (stat(buffer, &st) == 0) {                 if (S_ISDIR(st.st_mode)) {                    if (!RemoveEmptyDirectories(buffer, true))                       empty = false;                    }                 else                    empty = false;                 }              else {                 LOG_ERROR_STR(buffer);                 free(buffer);                 return false;                 }              free(buffer);              }           }     closedir(d);     if (RemoveThis && empty) {        dsyslog("removing %s", DirName);        if (remove(DirName) < 0) {           LOG_ERROR_STR(DirName);           return false;           }        }     return empty;     }  else     LOG_ERROR_STR(DirName);  return false;}char *ReadLink(const char *FileName){  char RealName[PATH_MAX];  const char *TargetName = NULL;  int n = readlink(FileName, RealName, sizeof(RealName) - 1);  if (n < 0) {     if (errno == ENOENT || errno == EINVAL) // file doesn't exist or is not a symlink        TargetName = FileName;     else // some other error occurred        LOG_ERROR_STR(FileName);     }  else if (n < int(sizeof(RealName))) { // got it!     RealName[n] = 0;     TargetName = RealName;     }  else     esyslog("ERROR: symlink's target name too long: %s", FileName);  return TargetName ? strdup(TargetName) : NULL;}bool SpinUpDisk(const char *FileName){  static char *buf = NULL;  for (int n = 0; n < 10; n++) {      free(buf);      if (DirectoryOk(FileName))         asprintf(&buf, "%s/vdr-%06d", *FileName ? FileName : ".", n);      else         asprintf(&buf, "%s.vdr-%06d", FileName, n);      if (access(buf, F_OK) != 0) { // the file does not exist         timeval tp1, tp2;         gettimeofday(&tp1, NULL);         int f = open(buf, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);         // O_SYNC doesn't work on all file systems         if (f >= 0) {            close(f);            system("sync");            remove(buf);            gettimeofday(&tp2, NULL);            double seconds = (((long long)tp2.tv_sec * 1000000 + tp2.tv_usec) - ((long long)tp1.tv_sec * 1000000 + tp1.tv_usec)) / 1000000.0;            if (seconds > 0.5)               dsyslog("SpinUpDisk took %.2f seconds\n", seconds);

⌨️ 快捷键说明

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