pkg://xcdroast-debuginfo-0.98a15-14.fc7.ppc.rpm:614443/
usr/
src/
debug/
xcdroast-0.98alpha15/
src/tools.c
info downloads
/*
tools.c
27.3.99 tn
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#if HAVE_LOCALE_H
#include <locale.h>
#else
# define setlocale(Category, Locale)
#endif
#include "gettext.h"
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <ctype.h>
#include <pwd.h>
#if ENABLE_NLS
# define _(String) gettext (String)
# define N_(String) gettext_noop (String)
#else
# define _(String) (String)
# define N_(String) (String)
#endif
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "xcdrdata.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 not a directory and 0 if or invalid path */
gint is_not_directory(gchar *path) {
struct stat buf;
if (stat(path,&buf) != 0) {
return 0;
}
if (S_ISDIR(buf.st_mode) == 0) {
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 the base directory of a given path, or NULL when invalid */
/* warning..overwrites original str */
gchar *get_basedir(gchar *dir) {
gchar *p;
/* nothing to do if this is already a directory */
if (is_directory(dir)) {
return dir;
}
/* look for last slash */
p = rindex(dir,'/');
if (p) {
*p = '\0';
if (strcmp(dir,"") == 0) {
strcpy(dir,"/");
}
return dir;
}
return NULL;
}
/* return the pure filename of a given path */
gchar *get_purefile(gchar *dir, gchar *out) {
gchar *p;
/* look for last slash */
p = rindex(dir,'/');
if (p) {
strncpy(out, p+1, MAXLINE);
} else {
strncpy(out, dir, MAXLINE);
}
return out;
}
/* 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' && str[j] != '\r')
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;
guint 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;
guint 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;
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);
}
/* another variant of escaping. Just required to escape = on the command
line of mkisofs directly */
gchar *convert_escape3(gchar *str) {
gchar tmp[MAXLINE*2];
gchar c,d;
guint 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;
case '=':
d = '=';
break;
}
if (d != '\0') {
/* generate escaped char */
tmp[j] = '\\'; j++;
/* escape the =-sign double! */
if (d == '=') {
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);
}
/* convert escape-chars in string -> e.g. newline to \n */
/* this versions will not escape quotes..required for master-path-lists */
gchar *convert_escape2(gchar *str) {
gchar tmp[MAXLINE*2];
gchar c,d;
guint 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) {
guint 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;
guint 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));
}
}
/*
* Use this version to work around some of the critical races
* such as bz 127658. This issue should be solved on a case by case basis.
* Expected side effects: GUI freezes (e.g. if called from read_write_out() in io.c).
*/
gint read_line_wait(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 {
/* Partial line read. Wait a
* bit longer in case there's
* more. This does not fix
* all the races in the
* parsing code, but works
* around them somewhat. */
struct timeval t;
fd_set set;
FD_ZERO(&set);
FD_SET(fd,&set);
t.tv_sec = 1;
t.tv_usec = 0;
if (select (fd+1, &set, NULL,
NULL, &t) > 0)
continue;
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;
}
/* extract single quotes-delimted string */
/* e.g.: 'bla' -> bla */
gint extract_singlequoted(gchar *str) {
gchar *p, *p2;
gchar tmp[MAXLINE];
strcpy(tmp,str);
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(str,p2);
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 */
/* warning - in some cases $HOME is not correct when user root */
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 (!isroot()) {
/* we are not root, trust $HOME */
if (g_get_home_dir()) {
strcpy(tmp, g_get_home_dir());
}
} else {
/* as root $HOME is often wrong - override */
if (get_pw_home(0)) {
strcpy(tmp, get_pw_home(0));
}
}
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];
strncpy(line,iline, MAXLINE);
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;
}
/* parse config line and return id and value, value2 */
/* form is ID = "val1","val2" */
/* return 0 if ok, 1 on error */
gint parse_config_line2(gchar *iline, gchar *id, gchar *value, gchar *value2) {
gchar *p,*p2;
gchar line[1024];
gchar tmp[1024];
strncpy(line,iline,MAXLINE);
strcpy(id,"");
strcpy(value,"");
strcpy(value2,"");
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(line,p2);
/* now in line is someling like xxx","yyy */
p = strstr(line,"\",\"");
if (p) {
*p = '\0';
strcpy(value,line);
strcpy(value2,p+3);
}
/* now reconvert escape-chars */
escape_parse(value);
escape_parse(value2);
/* all ok */
return 0;
}
/* check if we are root */
gint isroot() {
if (geteuid() == 0) {
return 1;
} else {
return 0;
}
}
/* check if user exists */
gint check_pw_user(gchar *name) {
struct passwd *ent;
ent = getpwnam(name);
if (ent) return 1;
return 0;
}
/* return the homedir (as in /etc/passwd) for a given user */
gchar *get_pw_home(gint uid) {
struct passwd *ent;
ent = getpwuid(uid);
if (ent)
return ent->pw_dir;
else
return NULL;
}
/* return the owner (uid) of a given file */
gint get_file_owner(gchar *path) {
struct stat buf;
if (stat(path,&buf) != 0) {
return -1;
}
return (buf.st_uid);
}
/* does move a text file */
gint move_textfile(gchar *src, gchar *target) {
FILE *fd, *fd2;
gchar line[MAXLINE];
fd = fopen(src,"r");
if (!fd) {
/* src file failed to open */
return 1;
}
fd2 = fopen(target,"w");
if (!fd2) {
/* target file failed to open */
fclose(fd);
return 1;
}
/* copy file line by line */
for (;;) {
if (fgets(line,MAXLINE,fd) == NULL)
break;
fputs(line,fd2);
}
fclose(fd2);
fclose(fd);
/* now delete the src file */
unlink(src);
return 0;
}
/* checks if a given file is a link. If so return 1 */
/* return the value of the link too, if requested */
gint check_islink(gchar *file, gchar *link) {
struct stat buf;
if (lstat(file, &buf) == 0) {
if (S_ISLNK(buf.st_mode)) {
if (link) {
memset(link, 0, MAXLINE);
if (readlink(file, link, MAXLINE-1) <= 0) {
strcpy(link, "?");
}
}
return 1;
}
}
return 0;
}
/* extract a readable string from a buffer */
void get_subheader(gchar *buf, gchar *text, gint start, gint end) {
gchar tmp[MAXLINE];
gchar c;
gint i,count;
count = 0;
for(i = start; i < end; i++) {
c = buf[i];
if (isprint((gint)c) || isspace((gint)c)) {
tmp[count++] = c;
}
}
tmp[count] = '\0';
for(i = strlen(tmp)-1; i >= 0; i--) {
if(tmp[i] != 0 && tmp[i] != ' ') {
tmp[i+1] = '\0';
break;
}
}
strip_string(tmp);
strcpy(text, tmp);
}
/* URL decoding - used because drag&drop names are often URL encoded */
/* borrowed from php4 source code (php4/ext/standard/url.c) */
static gint url_htoi(gchar *s) {
gint value;
gint c;
c = s[0];
if (isupper(c))
c = tolower(c);
value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
c = s[1];
if (isupper(c))
c = tolower(c);
value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
return (value);
}
gchar *url_decode(gchar *str, gint len) {
gchar *dest = str;
gchar *data = str;
while (len--) {
if (*data == '+')
*dest = ' ';
else if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) && isxdigit((int) *(data + 2))) {
*dest = (gchar) url_htoi(data + 1);
data += 2;
len -= 2;
} else
*dest = *data;
data++;
dest++;
}
*dest = '\0';
return dest;
}
/* URL encoding - used because drag&drop names are often URL encoded */
/* borrowed from php4 source code (php4/ext/standard/url.c) */
static unsigned char hexchars[] = "0123456789ABCDEF";
/* encode all special chars, but not / - and . */
gchar *url_encode(gchar *s, gint len, gint *new_length) {
gint x, y;
guchar *str;
str = (guchar *) g_new0(guchar *, 3 * len + 1);
for (x = 0, y = 0; len--; x++, y++) {
str[y] = (guchar) s[x];
if (str[y] == ' ') {
str[y] = '+';
} else if ((str[y] < '0' && str[y] != '-' && str[y] != '.' && str[y] != '/') ||
(str[y] < 'A' && str[y] > '9') ||
(str[y] > 'Z' && str[y] < 'a' && str[y] != '_') ||
(str[y] > 'z')) {
str[y++] = '%';
str[y++] = hexchars[(guchar) s[x] >> 4];
str[y] = hexchars[(guchar) s[x] & 15];
}
}
str[y] = '\0';
if (new_length) {
*new_length = y;
}
return ((gchar *) str);
}
/* extract the first filename from a set of data received from a drag
operation - return 1 on success */
gint extract_single_drag_filename(gchar *dragtext, gint draglen, gchar *rettext) {
gchar *p;
gchar tmp[MAXLINE];
gint len;
/* if we got serveral filenames only use the first */
if (dragtext) {
p = index(dragtext,'\r');
if (p) {
len = p - dragtext;
if (len < MAXLINE) {
strncpy(tmp,dragtext,len);
tmp[len] = '\0';
} else {
return 0;
}
} else {
strncpy(tmp,dragtext, MAXLINE);
}
/* extracted a single item */
strip_string(tmp);
/* does it begin with file:? */
if (strncmp(tmp,"file:", 5) == 0) {
/* two slashes at front? */
if (strlen(tmp) > 7 && tmp[5] == '/' && tmp[6] == '/') {
/* three slashes? */
if (strlen(tmp) > 8 && tmp[7] == '/') {
strncpy(rettext,tmp+7, MAXLINE);
/* url_decode only this case */
url_decode(rettext, strlen(rettext));
} else {
strncpy(rettext,tmp+6, MAXLINE);
}
} else {
strncpy(rettext,tmp+5, MAXLINE);
}
return 1;
}
}
return 0;
}
/* extract the a list of filename from a set of data received from a drag
operation - return 1 on success */
gint extract_glist_drag_filenames(gchar *dragtext, gint draglen, gchar *match, GList **dst) {
gchar *p, *buf;
gchar tmp[MAXLINE], tmp2[MAXLINE];
gint count;
count = 0;
/* if we got serveral filenames only use the first */
if (dragtext) {
/* allocate a tmp buffer for the drag data */
buf = g_strdup(dragtext);
p = strtok(buf,"\r\n");
while (p) {
strncpy(tmp, p, MAXLINE);
strip_string(tmp);
/* does it begin with file:? */
if (strncmp(tmp,match, 5) == 0) {
/* two slashes at front? */
if (strlen(tmp) > 7 && tmp[5] == '/' && tmp[6] == '/') {
/* three slashes? */
if (strlen(tmp) > 8 && tmp[7] == '/') {
strncpy(tmp2,tmp+7, MAXLINE);
/* url decode this case */
url_decode(tmp2, strlen(tmp2));
} else {
strncpy(tmp2,tmp+6, MAXLINE);
}
} else {
strncpy(tmp2,tmp+5, MAXLINE);
}
*dst = g_list_append(*dst, g_strdup(tmp2)); count++;
}
p = strtok(NULL,"\r\n");
}
g_free(buf);
}
if (count > 0) {
return 1;
} else {
return 0;
}
}
/* return 1 when invalid MCN number */
/* code from cdrtools auinfo.c */
gint verify_mcn(gchar *mcn) {
gchar *p;
/* wrong length? */
if (strlen(mcn) != 13) {
return 1;
}
for (p = mcn; *p; p++) {
/* illegal chars in string? */
if (*p < '0' || *p > '9') {
return 1;
}
}
return 0;
}
/* return 1 when invalid ISRC number */
/* code from cdrtools auinfo.c */
gint verify_isrc(gchar *isrc) {
gchar upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
gchar ibuf[13];
gchar *ip, *p;
gint i, len;
if ((len = strlen(isrc)) != 12) {
for (p = isrc, i = 0; *p; p++) {
if (*p == '-')
i++;
}
if (((len - i) != 12) || i > 3) {
/* illegal length */
return 1;
}
}
/* check country code */
for (p = isrc, ip = ibuf, i = 0; i < 2; p++, i++) {
*ip++ = *p;
if (!strchr(upper, *p)) {
/* allow numbers even when not expected */
if (*p >= '0' && *p <= '9')
continue;
return 1;
}
}
if (*p == '-')
p++;
/* owner code */
for (i = 0; i < 3; p++, i++) {
*ip++ = *p;
if (strchr(upper, *p))
continue;
if (*p >= '0' && *p <= '9')
continue;
return 1;
}
if (*p == '-')
p++;
/* year and recording number */
for (i = 0; i < 7; p++, i++) {
*ip++ = *p;
if (*p >= '0' && *p <= '9')
continue;
if (*p == '-' && i == 2) {
ip--;
i--;
continue;
}
return 1;
}
return 0;
}
/* remove one path level from a given path */
/* if we are already at root level return emtpy string */
gchar *get_reducedpath(gchar *dir, gchar *out) {
gchar *p;
gchar tmp[MAXLINE];
/* trailing slash? remove it first */
strncpy(tmp, dir, MAXLINE);
if (tmp[strlen(tmp)-1] == '/') {
tmp[strlen(tmp)-1] = '\0';
}
/* look for last slash */
p = rindex(tmp,'/');
if (p) {
/* cut it */
*p = '\0';
}
strncpy(out, tmp, MAXLINE);
return out;
}