6 static int thread_cmp(const void *v1
, const void *v2
)
8 struct thread
*t1
= *(struct thread
**) v1
;
9 struct thread
*t2
= *(struct thread
**) v2
;
10 if (t1
->id_len
!= t2
->id_len
)
11 return t2
->id_len
- t1
->id_len
;
12 return strncmp(t1
->id
, t2
->id
, t1
->id_len
);
15 static int id_cmp(char *i1
, int l1
, char *i2
, int l2
)
19 return strncmp(i1
, i2
, l1
);
22 static struct thread
*find_msg(struct thread
**msgs
, int n
, char *id
, int len
)
28 int d
= id_cmp(id
, len
, msgs
[m
]->id
, msgs
[m
]->id_len
);
39 static void create_tree(struct sort
*sort
, int beg
)
42 for (i
= beg
; i
< sort
->n
; i
++) {
43 struct thread
*msg
= &sort
->threads
[i
];
47 dad
= find_msg(sort
->id_sorted
, sort
->n
,
48 msg
->rply
, msg
->rply_len
);
49 if (!dad
|| dad
>= msg
)
52 if (!msg
->parent
->head
)
53 msg
->parent
->head
= msg
;
55 msg
->parent
->tail
->next
= msg
;
56 msg
->parent
->tail
= msg
;
60 static struct thread
**put_thread(struct thread
**sorted
, struct thread
*msg
)
62 struct thread
*cur
= msg
->head
;
65 sorted
= put_thread(sorted
, cur
);
71 static void make_sorted(struct sort
*sort
)
74 struct thread
**sorted
= sort
->sorted
;
75 for (i
= 0; i
< sort
->n
; i
++)
76 if (!sort
->threads
[i
].parent
)
77 sorted
= put_thread(sorted
, &sort
->threads
[i
]);
78 for (i
= 0; i
< sort
->n
; i
++)
79 sort
->mails
[i
] = sort
->sorted
[i
]->mail
;
82 static void make_hdrs(struct thread
*msg
)
84 char *id_hdr
= mail_hdr(msg
->mail
, "Message-ID:");
85 char *rply_hdr
= mail_hdr(msg
->mail
, "In-Reply-To:");
87 int len
= hdr_len(id_hdr
);
88 char *beg
= memchr(id_hdr
, '<', len
);
89 char *end
= beg
? memchr(id_hdr
, '>', len
) : NULL
;
94 msg
->id_len
= end
- beg
;
98 int len
= hdr_len(rply_hdr
);
99 char *beg
= memchr(rply_hdr
, '<', len
);
100 char *end
= beg
? memchr(rply_hdr
, '>', len
) : NULL
;
105 msg
->rply_len
= end
- beg
;
110 void sort_inc(struct sort
*sort
)
112 struct mbox
*mbox
= sort
->mbox
;
115 if (sort
->n
== mbox
->n
)
118 for (i
= beg
; i
< sort
->n
; i
++) {
119 struct thread
*thread
= &sort
->threads
[i
];
120 struct mail
*mail
= &mbox
->mails
[i
];
122 if (sort
->kind
& SORT_THREAD
) {
123 sort
->id_sorted
[i
] = thread
;
126 sort
->mails
[i
] = mail
;
127 sort
->sorted
[i
] = thread
;
130 if (sort
->kind
& SORT_THREAD
) {
131 qsort(sort
->id_sorted
, sort
->n
,
132 sizeof(*sort
->id_sorted
), thread_cmp
);
133 create_tree(sort
, beg
);
138 struct sort
*sort_alloc(struct mbox
*mbox
, int kind
)
140 struct sort
*sort
= malloc(sizeof(*sort
));
141 memset(sort
, 0, sizeof(*sort
));
148 void sort_free(struct sort
*sort
)
153 int sort_level(struct sort
*sort
, int id
)
155 struct thread
*msg
= sort
->sorted
[id
];
157 while ((msg
= msg
->parent
))