2016-07-17 19:51:41 +00:00
|
|
|
#include <sys/stat.h>
|
2016-07-18 15:06:41 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
|
2016-07-20 17:25:00 +00:00
|
|
|
#include <dirent.h>
|
2016-07-18 15:06:41 +00:00
|
|
|
#include <errno.h>
|
2016-07-17 19:51:41 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <limits.h>
|
2016-07-18 16:32:12 +00:00
|
|
|
#include <pwd.h>
|
2016-07-17 19:51:41 +00:00
|
|
|
#include <search.h>
|
2016-07-18 15:06:41 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
2016-07-17 19:51:41 +00:00
|
|
|
|
|
|
|
#include "blaze822.h"
|
|
|
|
#include "blaze822_priv.h"
|
|
|
|
|
2016-07-20 12:07:46 +00:00
|
|
|
char *
|
|
|
|
blaze822_home_file(char *basename)
|
2016-07-18 16:32:12 +00:00
|
|
|
{
|
|
|
|
static char path[PATH_MAX];
|
|
|
|
static char *homedir;
|
2016-09-01 23:50:20 +00:00
|
|
|
static char *profile;
|
|
|
|
|
|
|
|
if (!profile)
|
|
|
|
profile = getenv("MBLAZE");
|
|
|
|
if (profile) {
|
|
|
|
snprintf(path, sizeof path, "%s/%s", profile, basename);
|
|
|
|
return path;
|
|
|
|
}
|
2016-07-18 16:32:12 +00:00
|
|
|
|
|
|
|
if (!homedir)
|
|
|
|
homedir = getenv("HOME");
|
2016-09-01 18:56:54 +00:00
|
|
|
if (homedir && !*homedir)
|
|
|
|
homedir = 0;
|
|
|
|
if (!homedir) {
|
|
|
|
struct passwd *pw = getpwuid(getuid());
|
|
|
|
if (pw)
|
|
|
|
homedir = pw->pw_dir;
|
|
|
|
}
|
2016-07-18 16:32:12 +00:00
|
|
|
if (!homedir)
|
2016-09-01 18:56:54 +00:00
|
|
|
return "/dev/null/homeless";
|
2016-07-18 16:32:12 +00:00
|
|
|
|
2016-09-01 23:50:20 +00:00
|
|
|
snprintf(path, sizeof path, "%s/.mblaze/%s", homedir, basename);
|
2016-07-18 16:32:12 +00:00
|
|
|
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2016-07-17 19:51:41 +00:00
|
|
|
char *
|
|
|
|
blaze822_seq_open(char *file)
|
|
|
|
{
|
|
|
|
if (!file)
|
2016-07-26 14:55:55 +00:00
|
|
|
file = getenv("MAILSEQ");
|
2016-07-18 16:32:12 +00:00
|
|
|
if (!file)
|
2016-09-01 23:50:20 +00:00
|
|
|
file = blaze822_home_file("seq");
|
2016-07-17 19:51:41 +00:00
|
|
|
|
2016-10-05 12:44:36 +00:00
|
|
|
char *map;
|
|
|
|
off_t len;
|
2017-06-29 13:04:57 +00:00
|
|
|
int r = slurp(file, &map, &len);
|
|
|
|
if (r != 0) {
|
|
|
|
fprintf(stderr, "could not read sequence '%s': %s\n",
|
|
|
|
file, strerror(r));
|
2016-07-17 19:51:41 +00:00
|
|
|
return 0;
|
2017-06-29 13:04:57 +00:00
|
|
|
}
|
2016-07-17 19:51:41 +00:00
|
|
|
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *msgnums;
|
|
|
|
|
|
|
|
struct msgnum {
|
|
|
|
char *file;
|
|
|
|
long pos;
|
|
|
|
};
|
|
|
|
|
|
|
|
int
|
|
|
|
msgnumorder(const void *a, const void *b)
|
|
|
|
{
|
2017-01-26 19:27:26 +00:00
|
|
|
struct msgnum *ia = (struct msgnum *)a;
|
|
|
|
struct msgnum *ib = (struct msgnum *)b;
|
2016-07-17 19:51:41 +00:00
|
|
|
|
2017-01-26 19:27:26 +00:00
|
|
|
return strcmp(ia->file, ib->file);
|
2016-07-17 19:51:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
long
|
|
|
|
blaze822_seq_find(char *file)
|
|
|
|
{
|
|
|
|
struct msgnum key, **result;
|
2017-01-26 19:27:26 +00:00
|
|
|
key.file = file;
|
2016-07-17 19:51:41 +00:00
|
|
|
|
2017-01-26 19:27:26 +00:00
|
|
|
if (!(result = tfind(&key, &msgnums, msgnumorder)))
|
2016-07-17 19:51:41 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
return (*result)->pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
blaze822_seq_load(char *map)
|
|
|
|
{
|
|
|
|
char *s, *t;
|
|
|
|
long line;
|
|
|
|
|
|
|
|
for (s = map, line = 0; s; s = t+1) {
|
|
|
|
t = strchr(s, '\n');
|
|
|
|
if (!t)
|
|
|
|
break;
|
|
|
|
line++;
|
|
|
|
while (*s && iswsp(*s))
|
|
|
|
s++;
|
|
|
|
char *e = t;
|
|
|
|
while (s < e && isfws(*(e-1)))
|
|
|
|
e--;
|
|
|
|
// printf("{%.*s}\n", e-s, s);
|
|
|
|
char *f = strndup(s, e-s);
|
|
|
|
if (!f)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
struct msgnum key, **result;
|
|
|
|
key.file = f;
|
|
|
|
|
|
|
|
if (!(result = tfind(&key, &msgnums, msgnumorder))) {
|
|
|
|
struct msgnum *c = malloc(sizeof (struct msgnum));
|
|
|
|
c->file = f;
|
|
|
|
c->pos = line;
|
|
|
|
tsearch(c, &msgnums, msgnumorder);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2016-07-17 22:09:23 +00:00
|
|
|
|
|
|
|
char *
|
2016-09-01 13:42:35 +00:00
|
|
|
blaze822_seq_cur(void)
|
2016-07-17 22:09:23 +00:00
|
|
|
{
|
2017-01-26 19:27:26 +00:00
|
|
|
static char b[PATH_MAX];
|
2016-07-18 16:32:12 +00:00
|
|
|
|
2016-08-09 16:55:29 +00:00
|
|
|
char *override = getenv("MAILDOT");
|
|
|
|
if (override)
|
|
|
|
return override;
|
|
|
|
|
2016-07-18 16:32:12 +00:00
|
|
|
char *curlink = getenv("MAILCUR");
|
|
|
|
if (!curlink)
|
2016-09-01 23:50:20 +00:00
|
|
|
curlink = blaze822_home_file("cur");
|
2016-07-18 16:32:12 +00:00
|
|
|
|
|
|
|
int r = readlink(curlink, b, sizeof b - 1);
|
|
|
|
if (r < 0)
|
2016-07-17 22:09:23 +00:00
|
|
|
return 0;
|
2016-07-18 16:32:12 +00:00
|
|
|
b[r] = 0;
|
|
|
|
return b;
|
2016-07-17 22:09:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
blaze822_seq_setcur(char *s)
|
|
|
|
{
|
2016-08-09 16:55:29 +00:00
|
|
|
char *override = getenv("MAILDOT");
|
|
|
|
if (override)
|
|
|
|
return 0;
|
|
|
|
|
2016-07-18 16:32:12 +00:00
|
|
|
char curtmplink[PATH_MAX];
|
|
|
|
char *curlink = getenv("MAILCUR");
|
|
|
|
if (!curlink)
|
2016-09-01 23:50:20 +00:00
|
|
|
curlink = blaze822_home_file("cur");
|
2016-07-18 16:32:12 +00:00
|
|
|
|
|
|
|
if (snprintf(curtmplink, sizeof curtmplink, "%s-", curlink) >= PATH_MAX)
|
|
|
|
return -1; // truncation
|
|
|
|
|
|
|
|
if (unlink(curtmplink) < 0 && errno != ENOENT)
|
2016-07-17 22:09:23 +00:00
|
|
|
return -1;
|
2016-07-18 16:32:12 +00:00
|
|
|
if (symlink(s, curtmplink) < 0)
|
2016-07-17 22:09:23 +00:00
|
|
|
return -1;
|
2016-07-18 16:32:12 +00:00
|
|
|
if (rename(curtmplink, curlink) < 0)
|
2016-07-17 22:09:23 +00:00
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
parse_relnum(char *a, long cur, long last, long *out)
|
|
|
|
{
|
|
|
|
long base;
|
|
|
|
char *b;
|
|
|
|
|
|
|
|
if (strcmp(a, "+") == 0)
|
|
|
|
a = ".+1";
|
|
|
|
else if (strcmp(a, "-") == 0)
|
|
|
|
a = ".-1";
|
2016-07-24 21:10:58 +00:00
|
|
|
else if (strcmp(a, ".") == 0)
|
|
|
|
a = ".+0";
|
2016-07-17 22:09:23 +00:00
|
|
|
else if (strcmp(a, "$") == 0)
|
|
|
|
a = "-1";
|
|
|
|
|
|
|
|
if (*a == '.') {
|
|
|
|
a++;
|
|
|
|
base = cur;
|
|
|
|
} else if (*a == '-') {
|
|
|
|
base = last + 1;
|
|
|
|
} else {
|
|
|
|
base = 0;
|
|
|
|
}
|
2016-07-28 17:51:11 +00:00
|
|
|
|
|
|
|
long d;
|
|
|
|
if (*a == ':') {
|
|
|
|
d = 0;
|
|
|
|
b = a;
|
|
|
|
} else {
|
|
|
|
errno = 0;
|
|
|
|
d = strtol(a, &b, 10);
|
|
|
|
if (errno != 0) {
|
|
|
|
perror("strtol");
|
2016-08-08 12:23:34 +00:00
|
|
|
exit(2);
|
2016-07-28 17:51:11 +00:00
|
|
|
}
|
2016-07-17 22:09:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*out = base + d;
|
|
|
|
if (*out <= 0)
|
|
|
|
*out = 1;
|
|
|
|
if (*out > last)
|
|
|
|
*out = last;
|
|
|
|
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2016-08-05 18:05:24 +00:00
|
|
|
parse_thread(char *map, long a, long *starto, long *stopo)
|
|
|
|
{
|
|
|
|
char *s, *t;
|
|
|
|
long line;
|
|
|
|
|
|
|
|
long start = 0, stop = 0, state = 0;
|
|
|
|
|
|
|
|
for (s = map, line = 0; s; s = t+1) {
|
|
|
|
t = strchr(s, '\n');
|
|
|
|
if (!t)
|
|
|
|
break;
|
|
|
|
line++;
|
|
|
|
if (!iswsp(*s)) {
|
|
|
|
if (state == 0) {
|
|
|
|
start = line;
|
|
|
|
} else if (state == 1) {
|
|
|
|
stop = line - 1;
|
|
|
|
state = 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (line == a)
|
|
|
|
state = 1;
|
|
|
|
while (*s && iswsp(*s))
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == 1) {
|
|
|
|
stop = line;
|
|
|
|
state = 2;
|
|
|
|
}
|
|
|
|
if (state == 2) {
|
|
|
|
*starto = start;
|
|
|
|
*stopo = stop;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
parse_subthread(char *map, long a, long *stopo)
|
|
|
|
{
|
|
|
|
char *s, *t;
|
|
|
|
long line;
|
|
|
|
|
|
|
|
long stop = 0;
|
|
|
|
int minindent = -1;
|
|
|
|
|
|
|
|
for (s = map, line = 0; s; s = t+1) {
|
|
|
|
t = strchr(s, '\n');
|
2017-04-01 15:16:29 +00:00
|
|
|
if (!t) {
|
|
|
|
minindent = -1;
|
2016-08-05 18:05:24 +00:00
|
|
|
break;
|
2017-04-01 15:16:29 +00:00
|
|
|
}
|
2016-08-05 18:05:24 +00:00
|
|
|
line++;
|
|
|
|
int indent = 0;
|
|
|
|
while (*s && iswsp(*s)) {
|
|
|
|
s++;
|
|
|
|
indent++;
|
|
|
|
}
|
|
|
|
if (line == a)
|
|
|
|
minindent = indent;
|
|
|
|
if (line > a && indent <= minindent) {
|
|
|
|
stop = line - 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (line < a)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (minindent == -1)
|
|
|
|
stop = line;
|
|
|
|
|
|
|
|
*stopo = stop;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
parse_parent(char *map, long *starto, long *stopo)
|
|
|
|
{
|
|
|
|
char *s, *t;
|
|
|
|
long line;
|
|
|
|
|
2016-08-07 15:38:38 +00:00
|
|
|
int previndent[256] = { 0 };
|
2016-08-05 18:05:24 +00:00
|
|
|
|
|
|
|
for (s = map, line = 0; s; s = t+1) {
|
|
|
|
t = strchr(s, '\n');
|
|
|
|
if (!t)
|
|
|
|
break;
|
|
|
|
line++;
|
|
|
|
int indent = 0;
|
|
|
|
while (*s && iswsp(*s)) {
|
|
|
|
s++;
|
|
|
|
indent++;
|
|
|
|
}
|
2016-08-07 15:38:38 +00:00
|
|
|
if (indent > 255)
|
|
|
|
indent = 255;
|
2016-08-05 18:05:24 +00:00
|
|
|
previndent[indent] = line;
|
|
|
|
if (line == *starto) {
|
|
|
|
if (previndent[indent-1]) {
|
|
|
|
*starto = *stopo = previndent[indent-1];
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
parse_range(char *map, char *a, long *start, long *stop, long cur, long lines)
|
2016-07-17 22:09:23 +00:00
|
|
|
{
|
|
|
|
*start = *stop = 1;
|
|
|
|
|
2016-08-05 18:05:24 +00:00
|
|
|
while (*a && *a != ':' && *a != '=' && *a != '_' && *a != '^') {
|
2016-07-17 22:09:23 +00:00
|
|
|
char *b = parse_relnum(a, cur, lines, start);
|
|
|
|
if (a == b)
|
|
|
|
return 0;
|
|
|
|
a = b;
|
|
|
|
}
|
2016-08-05 18:05:24 +00:00
|
|
|
|
|
|
|
while (*a == '^') {
|
|
|
|
a++;
|
|
|
|
if (!parse_parent(map, start, stop))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-07-17 22:09:23 +00:00
|
|
|
if (*a == ':') {
|
|
|
|
a++;
|
|
|
|
if (!*a) {
|
|
|
|
*stop = lines;
|
|
|
|
} else {
|
|
|
|
char *b = parse_relnum(a, cur, lines, stop);
|
|
|
|
if (a == b)
|
|
|
|
return 0;
|
|
|
|
}
|
2016-08-05 18:05:24 +00:00
|
|
|
} else if (*a == '=') {
|
|
|
|
return parse_thread(map, *start, start, stop);
|
|
|
|
} else if (*a == '_') {
|
|
|
|
return parse_subthread(map, *start, stop);
|
2016-07-17 22:09:23 +00:00
|
|
|
} else if (!*a) {
|
|
|
|
*stop = *start;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
find_cur(char *map, struct blaze822_seq_iter *iter)
|
|
|
|
{
|
|
|
|
char *s, *t;
|
|
|
|
long cur = 0;
|
|
|
|
const char *curfile = blaze822_seq_cur();
|
|
|
|
|
|
|
|
iter->lines = 0;
|
|
|
|
for (s = map; s; s = t+1) {
|
|
|
|
t = strchr(s, '\n');
|
|
|
|
if (!t)
|
|
|
|
break;
|
|
|
|
while (*s == ' ' || *s == '\t')
|
|
|
|
s++;
|
|
|
|
|
|
|
|
// printf("{%.*s}\n", t-s, s);
|
|
|
|
iter->lines++;
|
|
|
|
if (!cur && curfile &&
|
|
|
|
strncmp(s, curfile, strlen(curfile)) == 0 &&
|
|
|
|
(s[strlen(curfile)] == '\n' ||
|
|
|
|
s[strlen(curfile)] == ' ' ||
|
|
|
|
s[strlen(curfile)] == '\t'))
|
|
|
|
iter->cur = iter->lines;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
blaze822_seq_next(char *map, char *range, struct blaze822_seq_iter *iter)
|
|
|
|
{
|
2016-07-26 15:14:40 +00:00
|
|
|
if (strcmp(range, ".") == 0) {
|
2016-12-31 12:25:56 +00:00
|
|
|
if (!iter->lines && !iter->start) {
|
2016-07-26 15:14:40 +00:00
|
|
|
iter->lines = 1;
|
2016-07-28 21:10:32 +00:00
|
|
|
find_cur(map, iter);
|
|
|
|
iter->start = iter->stop = iter->line = iter->cur + 1;
|
2016-07-31 14:53:02 +00:00
|
|
|
char *cur = blaze822_seq_cur();
|
|
|
|
return cur ? strdup(cur) : 0;
|
2016-07-26 15:14:40 +00:00
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-17 22:09:23 +00:00
|
|
|
if (!map)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!iter->lines) // count total lines
|
|
|
|
find_cur(map, iter);
|
|
|
|
|
|
|
|
if (!iter->start) {
|
2016-08-05 18:05:24 +00:00
|
|
|
if (!parse_range(map, range, &iter->start, &iter->stop,
|
2016-07-17 22:09:23 +00:00
|
|
|
iter->cur, iter->lines)) {
|
|
|
|
fprintf(stderr, "can't parse range: %s\n", range);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
iter->s = map;
|
|
|
|
iter->line = 1;
|
|
|
|
}
|
|
|
|
|
2016-07-20 10:22:23 +00:00
|
|
|
if (!iter->s)
|
|
|
|
return 0;
|
|
|
|
|
2016-07-17 22:09:23 +00:00
|
|
|
while (iter->line < iter->start) {
|
|
|
|
char *t = strchr(iter->s, '\n');
|
|
|
|
if (!t)
|
|
|
|
return 0;
|
|
|
|
iter->line++;
|
|
|
|
iter->s = t + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (iter->line > iter->stop) {
|
|
|
|
iter->start = iter->stop = 0; // reset iteration
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *t = strchr(iter->s, '\n');
|
|
|
|
if (!t)
|
|
|
|
return 0;
|
|
|
|
iter->cur = iter->line;
|
|
|
|
iter->line++;
|
|
|
|
char *r = strndup(iter->s, t-iter->s);
|
|
|
|
iter->s = t + 1;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2016-08-04 18:20:15 +00:00
|
|
|
static long
|
2016-07-26 11:46:47 +00:00
|
|
|
iterdir(char *dir, void (*cb)(char *))
|
2016-07-20 17:25:00 +00:00
|
|
|
{
|
|
|
|
DIR *fd, *fd2;
|
2017-01-26 19:27:26 +00:00
|
|
|
struct dirent *d;
|
2016-07-20 17:25:00 +00:00
|
|
|
|
2016-08-04 18:20:15 +00:00
|
|
|
long i = 0;
|
|
|
|
|
2016-07-20 17:25:00 +00:00
|
|
|
fd = opendir(dir);
|
|
|
|
if (!fd) {
|
|
|
|
if (errno == ENOTDIR)
|
|
|
|
cb(dir);
|
2016-08-04 18:20:15 +00:00
|
|
|
return 1;
|
2016-07-20 17:25:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char sub[PATH_MAX];
|
|
|
|
snprintf(sub, sizeof sub, "%s/cur", dir);
|
|
|
|
fd2 = opendir(sub);
|
|
|
|
if (fd2) {
|
|
|
|
closedir(fd);
|
|
|
|
fd = fd2;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ((d = readdir(fd))) {
|
2016-07-26 16:17:12 +00:00
|
|
|
#if defined(DT_REG) && defined(DT_UNKNOWN)
|
2016-07-20 17:25:00 +00:00
|
|
|
if (d->d_type != DT_REG && d->d_type != DT_UNKNOWN)
|
|
|
|
continue;
|
2016-07-26 16:17:12 +00:00
|
|
|
#endif
|
2016-07-20 17:25:00 +00:00
|
|
|
if (d->d_name[0] == '.')
|
|
|
|
continue;
|
|
|
|
if (fd2)
|
|
|
|
snprintf(sub, sizeof sub, "%s/cur/%s", dir, d->d_name);
|
|
|
|
else
|
|
|
|
snprintf(sub, sizeof sub, "%s/%s", dir, d->d_name);
|
|
|
|
cb(sub);
|
2016-08-04 18:20:15 +00:00
|
|
|
i++;
|
2016-07-20 17:25:00 +00:00
|
|
|
}
|
|
|
|
closedir(fd);
|
2016-08-04 18:20:15 +00:00
|
|
|
|
|
|
|
return i;
|
2016-07-20 17:25:00 +00:00
|
|
|
}
|
2016-07-17 22:09:23 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
blaze822_loop(int argc, char *argv[], void (*cb)(char *))
|
|
|
|
{
|
|
|
|
char *line = 0;
|
|
|
|
size_t linelen = 0;
|
|
|
|
ssize_t rd;
|
|
|
|
int i = 0;
|
|
|
|
|
2016-07-22 19:28:51 +00:00
|
|
|
if (argc == 0) {
|
2016-07-17 22:09:23 +00:00
|
|
|
while ((rd = getdelim(&line, &linelen, '\n', stdin)) != -1) {
|
|
|
|
if (line[rd-1] == '\n')
|
|
|
|
line[rd-1] = 0;
|
|
|
|
cb(line);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
free(line);
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *map = blaze822_seq_open(0);
|
|
|
|
struct blaze822_seq_iter iter = { 0 };
|
|
|
|
int j = 0;
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
|
|
if (strchr(argv[i], '/')) { // a file name
|
2016-08-04 18:20:15 +00:00
|
|
|
j += iterdir(argv[i], cb);
|
2016-07-17 22:09:23 +00:00
|
|
|
} else {
|
|
|
|
while ((line = blaze822_seq_next(map, argv[i], &iter))) {
|
|
|
|
cb(line);
|
|
|
|
free(line);
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return j;
|
|
|
|
}
|
2016-07-22 22:18:05 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
blaze822_loop1(char *arg, void (*cb)(char *))
|
|
|
|
{
|
|
|
|
char *args[] = { arg };
|
|
|
|
return blaze822_loop(1, args, cb);
|
|
|
|
}
|