📄 tools.c
字号:
/* tools.c 27.3.99 tn*/#include <stdio.h>#include <sys/stat.h>#include <unistd.h>#include <string.h>#include <dirent.h>#include <fcntl.h>#include <sys/types.h>#include <sys/time.h>#include <errno.h>#include <ctype.h>#include <gtk/gtk.h>#include <gdk/gdk.h>#include <gdk_imlib.h>#include "xcdroast.h"#include "main.h"/* return 1 if path is a directory and 0 if not or invalid path */gint is_directory(gchar *path) {struct stat buf; if (stat(path,&buf) != 0) { return 0; } if (S_ISDIR(buf.st_mode) == 1) { return 1; } else { return 0; }}/* return 1 if path is a file or directory and 0 if not or invalid path */gint is_file(gchar *path) {struct stat buf; if (stat(path,&buf) != 0) { return 0; } return 1;}/* return 1 when path contains a subdir, else 0 *//* skip . and ..-directories */gint is_subdirs(gchar *path) {struct dirent *ent;DIR *dir; gchar tmp[MAXLINE]; dir = opendir(path); /* invalid directory */ if (dir == NULL) return 0; while ( (ent = readdir(dir)) ) { strcpy(tmp,path); /* add slash when not there */ if (tmp[strlen(tmp)-1] != '/') strcat(tmp,"/"); strcat(tmp,ent->d_name); if (strcmp(ent->d_name,".") == 0 || strcmp(ent->d_name,"..") == 0) continue; if (is_directory(tmp)) { closedir(dir); return 1; } } closedir(dir); return 0;}/* return 1 when path contains files, else 0 *//* skip . and ..-directories */gint is_subfiles(gchar *path) {struct dirent *ent;DIR *dir; gchar tmp[MAXLINE]; dir = opendir(path); /* invalid directory */ if (dir == NULL) return 0; while ( (ent = readdir(dir)) ) { strcpy(tmp,path); /* add slash when not there */ if (tmp[strlen(tmp)-1] != '/') strcat(tmp,"/"); strcat(tmp,ent->d_name); if (strcmp(ent->d_name,".") == 0 || strcmp(ent->d_name,"..") == 0) continue; closedir(dir); return 1; } closedir(dir); return 0;}/* strip a string of leading and trailing whitespace */gchar *strip_string(gchar *str) {gint i,j;gint c1; if ( str == NULL) return (NULL); /* count how many leading chars to be whitespace */ for(i=0; i<strlen(str); i++) { if (str[i] != ' ' && str[i] != '\t' && str[i] != '\r') break; } /* count how many trailing chars to be whitespace */ for(j=strlen(str)-1; j >= 0; j--) { if (str[j] != ' ' && str[j] != '\t' && str[j] != '\n') break; } /* string contains only whitespace? */ if (j<i) { str[0] = '\0'; return(str); } /* now move the chars to the front */ for(c1=i; c1 <= j; c1++) { str[c1-i] = str[c1]; } str[j+1-i] = '\0'; return(str);}/* parse escape-chars in string -> e.g. translate \n to newline */gchar *escape_parse(gchar *str) {gchar tmp[MAXLINE];gchar c;gint i,j; if ( str == NULL) return (NULL); j = 0; for(i=0; i<strlen(str); i++) { c = str[i]; if (c == '\\') { i++; switch(str[i]) { case 'n': c = '\n'; break; case 't': c = '\t'; break; case 'b': c = '\b'; break; default: c = str[i]; } } tmp[j]=c; j++; } tmp[j] = '\0'; strcpy(str,tmp); return(str);}/* convert escape-chars in string -> e.g. newline to \n */gchar *convert_escape(gchar *str) {gchar tmp[MAXLINE*2];gchar c,d;gint i,j; if (str == NULL) return (NULL); j = 0; for (i = 0; i < strlen(str); i++) { c = str[i]; d = '\0'; switch (c) { case '\n': d = 'n'; break; case '\t': d = 't'; break; case '\b': d = 'b'; break; case '\\': d = '\\'; break; case '\"': d = '\"'; break; } if (d != '\0') { /* generate escaped char */ tmp[j] = '\\'; j++; tmp[j] = d; j++; } else { tmp[j] = c; j++; } } tmp[j] = '\0'; /* check if new string is not getting to long */ if (strlen(tmp) < MAXLINE) { strcpy(str,tmp); } else { /* over MAXLINE chars - should never happen */ /* cut off string */ strncpy(str,tmp,MAXLINE-1); str[MAXLINE-1] = '\0'; } return(str);}/* check if there are illegal chars in our string and replace them with _ *//* return 0 if all ok, and 1 if any chars changed/removed */gint remove_illegal_chars(gchar *str) {gint i,j; if (str == NULL) return 0; j = 0; for (i = 0; i < strlen(str); i++) { switch (str[i]) { case '/': case '\\': case '\b': case '\t': str[i] = '_'; j = 1; break; } } return(j);}/* get a string of the form "'xxx' from 'xxx'" and extract the strings xxx to artist and title. remove any escape characters. Return 0 if all ok, 1 on problems */ gint decode_title_artist(gchar *str, gchar *title, gchar *artist) {gchar tmp[MAXLINE];gchar tmp2[MAXLINE];gchar c,oldc;gint i; if (str == NULL) { return 1; } oldc = '\0'; /* check first char */ if (str[0] != '\'') { /* not right - abort */ return 1; } strcpy(tmp,str+1); /* look for next unescaped quote */ for (i = 0; i < strlen(tmp); i++) { c = tmp[i]; /* if current char ' and previous not \ we are done */ if ((c == '\'') && (oldc != '\\')) { break; } oldc = c; } if (i == strlen(tmp)) { /* no quote found at all */ return 1; } /* done extracting the title */ strncpy(title,tmp,i); title[i] = '\0'; /* now parse all other escaped chars */ escape_parse(title); /* now the artist-field */ strcpy(tmp2, tmp+i); if (strncmp(tmp2,"' from '",8) != 0) { /* look for middle string */ /* not fitting - abort */ return 1; } strcpy(tmp,tmp2+8); /* look for next unescaped quote */ for (i = 0; i < strlen(tmp); i++) { c = tmp[i]; /* if current char ' and previous not \ we are done */ if ((c == '\'') && (oldc != '\\')) { break; } oldc = c; } if (i == strlen(tmp)) { /* no quote found at all */ return 1; } /* done extracting the artist */ strncpy(artist,tmp,i); artist[i] = '\0'; /* now parse all other escaped chars */ escape_parse(artist); return 0;}/* * Read a line from a descriptor. Read the line one byte at a time, * looking for the newline. Works fine in nonblocking mode..here * we return when no more data can be read. * We overwrite the newline with a null. * We return the number of characters up to, but not including, * the null (the same as strlen(3)). */ gint read_line(gint fd, gchar *ptr, gint maxlen) {gint n, rc;gchar c;gchar *str; str = ptr; for (n = 1; n < maxlen; n++) { if ( (rc = read(fd, &c, 1)) == 1) { *ptr++ = c; if (c == '\n') { break; } } else if (rc == 0) { /* EOF */ if (n == 1) return(0); /* EOF, no data read */ else break; /* EOF, some data was read */ } else if (rc == -2) { /* timeout while reading string */ return(-2); } else { /* nonblocking mode an nothing to read? */ if (rc == -1 && errno == EAGAIN) { if (n == 1) return(-1); else break; } return(-1); /* error */ } } /* terminate the string */ *ptr = 0; /* strip of some trailing chars - yes..we need both levels */ ptr--; if ((*ptr == '\n') || (*ptr == '\r') ) { *ptr = 0; } ptr--; if ((*ptr == '\n') || (*ptr == '\r') ) { *ptr = 0; } if (strlen(str) == 0) { /* if we read an empty string, but are NOT on EOF return 1 */ return 1; } else { return(strlen(str)); }}/* extract quotes-delimted string after first colon *//* e.g.: 03: "bla" -> bla */gint extract_quoted(gchar *str) {gchar *p, *p2;gchar tmp[MAXLINE];gchar tmp2[MAXLINE]; strcpy(tmp,str); /* get string after first colon */ p = strtok(tmp,":"); if (p == NULL) return 1; p = strtok(NULL,""); if (p == NULL) return 1; strcpy(tmp,p); strip_string(tmp); /* now strip quotes */ p = tmp; if (*p == '\"') { p2 = p+1; } else { p2 = p; } if (p[strlen(p)-1] == '\"') { p[strlen(p)-1] = '\0'; } strcpy(tmp2,p2); escape_parse(tmp2); strcpy(str,tmp2); return 0;}/* read one char from a file descriptor with timeout *//* return 1 if char read ok, -1 on read error, -2 on timeout */gint get_char(gint fd, char *c) {gint j;struct timeval t;fd_set set; FD_ZERO(&set); FD_SET(fd,&set); t.tv_sec = NETIOTIMEOUT; t.tv_usec = 0; j = select(fd+1, &set, NULL, NULL, &t); if (j > 0) { return(read(fd, c, 1)); } else { /* timeout triggered */ return -2; }}/* * Read a line from a descriptor. Read the line one byte at a time, * looking for the newline. * We overwrite the newline with a null. * We return the number of characters up to, but not including, * the null (the same as strlen(3)). */ gint read_line2(gint fd, gchar *ptr, gint maxlen, gint timeout) {gint n, rc;gchar c; for (n = 1; n < maxlen; n++) { if (timeout) { /* use timeout */ rc = get_char(fd,&c); } else { rc = read(fd, &c, 1); } if ( rc == 1) { *ptr++ = c; if (c == '\n') { break; } } else if (rc == 0) { if (n == 1) return(0); /* EOF, no data read */ else break; /* EOF, some data was read */ } else if (rc == -2) { /* timeout while reading string */ return(-2); } else { return(-1); /* error */ } } /* strip of some trailing chars - yes..we need all three levels*/ if ((*ptr == '\n') || (*ptr == '\r') ) { *ptr = 0; } ptr--; if ((*ptr == '\n') || (*ptr == '\r') ) { *ptr = 0; } ptr--; if ((*ptr == '\n') || (*ptr == '\r') ) { *ptr = 0; } return(n);} /* * Write "n" bytes to a descriptor. * Use in place of write() when fd is a stream socket. */ gint writen(gint fd, gchar *ptr, gint nbytes, gint newline) {gint nleft, nwritten; nleft = nbytes; while (nleft > 0) { nwritten = write(fd, ptr, nleft); if (nwritten <= 0) return(nwritten); /* error */ nleft -= nwritten; ptr += nwritten; } /* add a newline when requested */ if (newline) { write(fd,"\n",1); } return(nbytes - nleft);}/* replace ~/ in an entry field by the home-directory */gchar *check_tilde(gchar *str) {gchar tmp[MAXLINE]; if (str == NULL) return str; strip_string(str); /* to short, do nothing */ if (strlen(str) < 2) return str; /* ~/ found? */ if (str[0] == '~' && str[1] == '/') { tmp[0] = '\0'; if (g_get_home_dir()) { strcpy(tmp, g_get_home_dir()); } strcat(tmp,"/"); strcat(tmp,str+2); strcpy(str,tmp); } return str;}/* parse config line and return id and value *//* return 0 if ok, 1 on error */gint parse_config_line(gchar *iline, gchar *id, gchar *value) {gchar *p,*p2;gchar line[1024];gchar tmp[1024]; strcpy(line,iline); strcpy(id,""); p = strtok(line,"="); if (p != NULL) { /* got id */ strcpy(id,p); strip_string(id); } else { return 1; } strcpy(tmp,""); p = strtok(NULL,""); if (p != NULL) { /* string after = */ strcpy(tmp,p); strip_string(tmp); } else { return 1; } /* now strip quotes from string */ p = tmp; if (*p == '\"') { p2 = p+1; } else { p2 = p; } if (p[strlen(p)-1] == '\"') { p[strlen(p)-1] = '\0'; } strcpy(value,p2); /* now reconvert escape-chars */ escape_parse(value); /* all ok */ return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -