void init_colors(void) { int i = 0; char *p, *e, *q, *org; unsigned int n; if(colors_initialized) return; p = getenv("LS_COLORS"); if(!p) p = getenv("LS_COLOURS"); if(p && *p) { org = p = xstrdup(p); n = strqnchr(p, ':')+2; clrs = (lscolor *)xmalloc(n * sizeof(lscolor)); e = strqsep(&p, ':'); while(e && *e) { q = strqsep(&e, '='); clrs[i].msk = xstrdup(q); q = strqsep(&e, ':'); clrs[i].clr = xstrdup(q); e = strqsep(&p, ':'); if(strcmp(clrs[i].msk, "di")==0) /* directory */ diclr = clrs[i].clr; else if(strcmp(clrs[i].msk, "ln")==0) /* link */ lnclr = clrs[i].clr; else if(strcmp(clrs[i].msk, "fi")==0) /* normal file */ ficlr = clrs[i].clr; else if(strcmp(clrs[i].msk, "ex")==0) /* executable */ exclr = clrs[i].clr; else if(strcmp(clrs[i].msk, "bd")==0) /* block device */ bdclr = clrs[i].clr; else if(strcmp(clrs[i].msk, "cd")==0) /* character device */ cdclr = clrs[i].clr; else if(strcmp(clrs[i].msk, "pi")==0) /* pipe */ piclr = clrs[i].clr; else if(strcmp(clrs[i].msk, "so")==0) /* socket */ soclr = clrs[i].clr; else if(strcmp(clrs[i].msk, "lc") == 0) /* left code */ lc = clrs[i].clr; else if(strcmp(clrs[i].msk, "rc") == 0) /* right code */ rc = clrs[i].clr; else if(strcmp(clrs[i].msk, "ec") == 0) /* end code (lc+fi+rc) */ ec = clrs[i].clr; else i++; } number_of_colors = i; free(org); if(!ec) { ec = xmalloc(strlen(lc)+strlen(ficlr)+strlen(rc)+1); sprintf(ec, "%s%s%s", lc, ficlr, rc); } } }
int GetParamObject(const char* pszString, const char* pszParam, int iDefault) { if (!pszString || !pszParam) return iDefault; char* pszRet = NULL; char* pszTemp = reinterpret_cast<char*>(alloca(strlen(pszString)+1)); if (!pszTemp) return 0; strcpy(pszTemp, pszString); char* pszSep, *pszToken; for (pszSep = pszTemp, pszToken = strqsep(&pszSep, g_pszParamDelim, g_pszQuotes); pszToken; pszToken = strqsep(&pszSep, g_pszParamDelim, g_pszQuotes)) { while (isspace(*pszToken)) ++pszToken; char* pszStart = strchr(pszToken, '='); if (pszStart) *pszStart++ = '\0'; if (!_stricmp(pszToken, pszParam)) { if (!pszStart) break; while (isspace(*pszStart)) ++pszStart; if (*pszStart == '"' || *pszStart == '\'') { char quote = *pszStart++; char* pszEnd = strrchr(pszStart, quote); if (!pszEnd) pszEnd = pszStart + strlen(pszStart); char* pszChar = pszRet = pszStart; while (pszStart < pszEnd) { if (*pszStart == '\\' && (pszStart[1] == '\\' || pszStart[1] == quote)) { ++pszStart; } *pszChar++ = *pszStart++; } *pszChar = '\0'; } else { int iLen = strlen(pszStart); pszRet = pszStart; pszRet[iLen] = '\0'; } break; } } int iRet = (pszRet) ? StrToObject(pszRet) : iDefault; return iRet; }
int GetParamTime(const char* pszString, const char* pszParam, int iDefault) { if (!pszString || !pszParam) return iDefault; int iRet = iDefault; char* pszTemp = reinterpret_cast<char*>(alloca(strlen(pszString)+1)); if (!pszTemp) return 0; strcpy(pszTemp, pszString); char* pszSep, *pszToken; for (pszSep = pszTemp, pszToken = strqsep(&pszSep, g_pszParamDelim, g_pszQuotes); pszToken; pszToken = strqsep(&pszSep, g_pszParamDelim, g_pszQuotes)) { while (isspace(*pszToken)) ++pszToken; char* pszStart = strchr(pszToken, '='); if (pszStart) *pszStart++ = '\0'; if (!_stricmp(pszToken, pszParam)) { if (!pszStart) break; while (isspace(*pszStart)) ++pszStart; char* pszEnd = pszStart + strlen(pszStart); if (*pszStart == '\"' || *pszStart == '\'') { if (*(pszEnd-1) == *pszStart) *(--pszEnd) = '\0'; ++pszStart; } if (*pszStart == '$') { ++pszStart; if (pszEnd > pszStart) { SService<IQuestSrv> pQS(g_pScriptManager); if (pQS->Exists(pszStart)) iRet = pQS->Get(pszStart); } } else { iRet = strtotime(pszStart); } break; } } return iRet; }
void listify_string(const char *str, list *lp) { char *e; char *s, *orgs; orgs = s = xstrdup(str); while((e = strqsep(&s, ':')) != 0) { if(list_search(lp, (listsearchfunc)strcmp, e) == 0) list_additem(lp, xstrdup(e)); } free(orgs); }
static int rfile_parse_eplf(rfile *f, char *str, const char *dirpath) { char *e; if(!str || str[0] != '+') return -1; str++; f->perm = xstrdup("-rw-r--r--"); f->size = 0L; f->mtime = 0; f->link = 0; f->nhl = 0; f->owner = xstrdup("owner"); f->group = xstrdup("group"); f->date = xstrdup("Jan 0 1900"); f->path = 0; while((e = strqsep(&str, ',')) != 0) { switch(*e) { case '/': f->perm[0] = 'd'; break; case 'm': f->mtime = strtoul(e+1, 0, 10); free(f->date); f->date = time_to_string(f->mtime); break; case 's': f->size = strtoull(e+1, 0, 10); break; case '\t': if (asprintf(&f->path, "%s/%s", strcmp(dirpath, "/") ? dirpath : "", e+1) == -1) f->path = NULL; break; } } if (!f->path) return -1; rfile_parse_colors(f); return 0; }
static char *guess_alias(url_t *url) { char *e, *p, *o, *maxp; int max = 0, len; if(!url) return 0; if(url->alias) return xstrdup(url->alias); o = e = xstrdup(url->hostname); if(!e) return 0; /* IP address? */ if(isdigit((int)e[0])) return e; maxp = e; while(true) { p = strqsep(&e, '.'); if(!p) break; if(*e == 0) { /* don't count the last part (the toplevel domain) */ break; } len = strlen(p); if(len >= max) { max = len; maxp = p; } } p = xstrdup(maxp); free(o); return p; }
/* creates path (and all elements in path) * PATH should be an absolute path * returns -1 on error, 0 if no directories created, else 1 */ int ftp_mkpath(const char *path) { bool one_created = false; char *p, *orgp, *e = 0; if(!path) return 0; /* check if we already has created this path */ if(ftp_path_part_of(path, ftp->last_mkpath)) return 0; /* check if this path is a part of current directory */ if(ftp_path_part_of(path, ftp->curdir)) return 0; orgp = p = xstrdup(path); path_collapse(p); unquote(p); if(*p == '/') { e = xmalloc(1); *e = 0; } while(true) { char *tmp, *foo; tmp = strqsep(&p, '/'); if(!tmp) break; if (e) { if (asprintf(&foo, "%s/%s", e, tmp) == -1) { fprintf(stderr, _("Failed to allocate memory.\n")); free(e); free(orgp); return -1; } } else foo = xstrdup(tmp); free(e); e = foo; /* check if we already has created this path */ if(ftp_path_part_of(e, ftp->last_mkpath)) continue; /* check if this path is a part of current directory */ if(ftp_path_part_of(e, ftp->curdir)) continue; if(strcmp(e, ".") != 0) { ftp_mkdir_verb(e, vbNone); one_created = (ftp->code == ctComplete); } } free(ftp->last_mkpath); ftp->last_mkpath = path_absolute(path, ftp->curdir, ftp->homedir); free(e); free(orgp); return one_created; }
rdirectory *ssh_read_directory(const char *path) { rdirectory *rdir; int i; SFTP_DIRENT **dir; char *p = ftp_path_absolute(path); stripslash(p); if(ssh_readdir(p, &dir) != 0) { free(p); return 0; } rdir = rdir_create(); ftp_trace("*** start parsing directory listing ***\n"); for(i = 0; dir[i]; i++) { rfile *rf; char *e, *cf = dir[i]->longname; ftp_trace("%s\n", dir[i]->longname); rf = rfile_create(); rf->perm = perm2string(dir[i]->a.perm); e = strqsep(&cf, ' '); /* skip permissions */ e = strqsep(&cf, ' '); /* nhl? */ /* if(ftp->ssh_version > 2) {*/ rf->nhl = atoi(e); /* } else*/ /* rf->nhl = 0;*/ #if 1 e = strqsep(&cf, ' '); rf->owner = xstrdup(e); e = strqsep(&cf, ' '); rf->group = xstrdup(e); #else asprintf(&rf->owner, "%d", dir[i]->a.uid); asprintf(&rf->group, "%d", dir[i]->a.gid); #endif asprintf(&rf->path, "%s/%s", p, dir[i]->filename); rf->mtime = dir[i]->a.mtime; if(rf->mtime == 0) { char *m, *d, *y; while(e && month_number(e) == -1) e = strqsep(&cf, ' '); if(e) { m = e; d = strqsep(&cf, ' '); y = strqsep(&cf, ' '); ftp_trace("parsing time: m:%s d:%s y:%s\n", m, d, y); rfile_parse_time(rf, m, d, y); } } rf->date = time_to_string(rf->mtime); rf->size = dir[i]->a.size; rfile_parse_colors(rf); rf->link = 0; if(rislink(rf) && ftp->ssh_version > 2) rf->link = ssh_readlink(rf->path); list_additem(rdir->files, (void *)rf); } ftp_trace("*** end parsing directory listing ***\n"); ssh_free_dirents(dir); rdir->path = p; ftp_trace("added directory '%s' to cache\n", p); list_additem(ftp->cache, rdir); return rdir; }
static int rfile_parse_mlsd(rfile *f, char *str, const char *dirpath) { char *e; bool isdir = false; if(!str) return -1; e = strchr(str, ' '); if(e) { if (asprintf(&f->path, "%s/%s", strcmp(dirpath, "/") ? dirpath : "", base_name_ptr(e+1)) == -1) { f->path = NULL; return -1; } *e = 0; } else return -1; f->perm = 0; f->size = 0L; f->mtime = 0; f->link = 0; f->nhl = 0; f->owner = xstrdup("owner"); f->group = xstrdup("group"); f->date = xstrdup("Jan 0 1900"); while((e = strqsep(&str, ';')) != 0) { char *factname, *value; factname = strqsep(&e, '='); value = e; if(!factname || !value) { return -1; } if(strcasecmp(factname, "size") == 0 || strcasecmp(factname, "sizd") == 0) /* the "sizd" fact is not standardized in "Extension to * FTP" Internet draft, but PureFTPd uses it for some * reason for size of directories */ f->size = strtoull(value,NULL,10); else if(strcasecmp(factname, "type") == 0) { if(strcasecmp(value, "file") == 0) isdir = false; else if(strcasecmp(value, "dir") == 0 || strcasecmp(value, "cdir") == 0 || strcasecmp(value, "pdir") == 0) isdir = true; } else if(strcasecmp(factname, "modify") == 0) { struct tm ts; sscanf(value, "%04d%02d%02d%02d%02d%02d", &ts.tm_year, &ts.tm_mon, &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec); ts.tm_year -= 1900; ts.tm_mon--; f->mtime = gmt_mktime(&ts); free(f->date); f->date = time_to_string(f->mtime); } else if(strcasecmp(factname, "UNIX.mode") == 0) { free(f->perm); f->perm = perm2string(strtoul(value, 0, 8)); } else if(strcasecmp(factname, "UNIX.gid") == 0) { free(f->group); f->group = xstrdup(value); } else if(strcasecmp(factname, "UNIX.uid") == 0) { free(f->owner); f->owner = xstrdup(value); } } if(!f->perm) f->perm = xstrdup("-rw-r--r--"); if(isdir) f->perm[0] = 'd'; rfile_parse_colors(f); return 0; }
/* This is a total mess! */ static int rfile_parse_unix(rfile *f, char *str, const char *dirpath) { char *cf; char *e; char *m=0, *d=0, *y=0; char *saved_field[5]; bool time_parsed = false; /* real unix ls listing: * * saved_field[0] == nhl * saved_field[1] == owner * saved_field[2] == group * saved_field[3] == size * saved_field[4] == month * * * unix w/o group listing: * * saved_field[0] == nhl * saved_field[1] == owner * saved_field[2] == size * saved_field[3] == month * saved_field[4] == date * * * strange MacOS WebStar thingy: * * saved_field[0] == size or "folder" * saved_field[1] == zero or date if [0]=="folder" * saved_field[2] == size (again!?) or month * saved_field[3] == month or date * saved_field[4] == date or time (or year?) * * * Linux netkit FTP server with LANG=sv_SE (ISO date&time format): * (-rw------- 1 mhe mhe 1422 2002-09-24 22:30 asdf.txt) * * saved_field[0] == nhl * saved_field[1] == owner * saved_field[2] == group * saved_field[3] == size * saved_field[4] == YYYY-MM-DD * */ if(strncmp(str, "total ", 6) == 0) return 1; if(strncmp(str, "insgesamt ", 10) == 0) // de "overall" return 1; cf = str; /* NEXT_FIELD; f->perm = xstrdup(e);*/ /* the above doesn't work here: * drwxrwxr-x156 31 20 29696 Apr 26 19:00 gnu * ----------^ * so we assume the permission string is exactly 10 characters */ f->perm = xstrndup(cf, 10); cf += 10; /* drwxr-s---+ 78 0 228 1536 Jul 10 15:36 private */ if(*cf == '+') ++cf; NEXT_FIELD; saved_field[0] = xstrdup(e); NEXT_FIELD; saved_field[1] = xstrdup(e); NEXT_FIELD; saved_field[2] = xstrdup(e); NEXT_FIELD; /* special device? */ if(e[strlen(e)-1] == ',') { NEXT_FIELD; } saved_field[3] = xstrdup(e); NEXT_FIELD; saved_field[4] = xstrdup(e); /* distinguish the different ls variants by looking * for the month field */ if(month_number(saved_field[4]) != -1) { /* ls -l */ f->nhl = atoi(saved_field[0]); free(saved_field[0]); f->owner = saved_field[1]; f->group = saved_field[2]; f->size = strtoull(saved_field[3],NULL,10); free(saved_field[3]); m = saved_field[4]; NEXT_FIELD2; d = xstrdup(e); NEXT_FIELD2; y = xstrdup(e); } else if(month_number(saved_field[3]) != -1) { /* ls -lG */ f->nhl = atoi(saved_field[0]); free(saved_field[0]); f->owner = saved_field[1]; f->group = xstrdup("group"); f->size = strtoull(saved_field[2],NULL,10); free(saved_field[2]); m = saved_field[3]; d = saved_field[4]; NEXT_FIELD2; y = xstrdup(e); } else if(month_number(saved_field[2]) != -1) { free(saved_field[0]); f->nhl = 0; f->owner = xstrdup("owner");; f->group = xstrdup("group"); f->size = strtoull(saved_field[1],NULL,10); free(saved_field[1]); m = saved_field[2]; d = saved_field[3]; y = saved_field[4]; } else { int iy, im, id, ih = 0, imin = 0; if(sscanf(saved_field[4], "%d-%d-%d", &iy, &im, &id) == 3) { /* date on the form YYYY-MM-DD */ im -= 1; /* should be 0-based */ f->nhl = atoi(saved_field[0]); free(saved_field[0]); f->owner = saved_field[1]; f->group = saved_field[2]; f->size = strtoull(saved_field[3],NULL,10); free(saved_field[3]); free(saved_field[4]); e = strqsep(&cf, ' '); /* HH:MM */ sscanf(e, "%d:%d", &ih, &imin); { struct tm mt; time_t now; f->mtime = (time_t)-1; mt.tm_sec = 0; mt.tm_min = imin; mt.tm_hour = ih; mt.tm_mday = id; mt.tm_mon = im; mt.tm_year = iy; mt.tm_isdst = -1; f->mtime = mktime(&mt); time(&now); bool success = true; if(f->mtime != (time_t)-1 && (now > f->mtime + 6L * 30L * 24L * 60L * 60L /* Old. */ || now < f->mtime - 60L * 60L)) /* In the future. */ { success = asprintf(&f->date, "%s %2d %5d", month_name[im], id, iy) != -1; } else { success = asprintf(&f->date, "%s %2d %02d:%02d", month_name[im], id, ih, imin) != -1; } if (!success) { f->date = NULL; return -1; } time_parsed = true; } } else { free(saved_field[0]); free(saved_field[1]); free(saved_field[2]); free(saved_field[3]); free(saved_field[4]); return -1; } } if(!time_parsed) { if (asprintf(&f->date, "%s %2s %5s", m, d, y) == -1) { free(m); free(d); free(y); f->date = NULL; return -1; } rfile_parse_time(f, m, d, y); if(f->mtime == (time_t)-1) ftp_trace("rfile_parse_time failed! date == '%s'\n", f->date); free(m); free(d); free(y); } if(!cf) return -1; e = strstr(cf, " -> "); if(e) { *e = 0; f->link = xstrdup(e+4); } if (asprintf(&f->path, "%s/%s", strcmp(dirpath, "/") ? dirpath : "", cf) == -1) { f->path = NULL; return -1; } rfile_parse_colors(f); return 0; }