You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

322 lines
7.2 KiB

26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
  1. #!/usr/bin/perl -w
  2. #
  3. # Prints mails to standard output
  4. #
  5. ####
  6. #### Standard inits and get options
  7. ####
  8. use DBI;
  9. use Getopt::Long;
  10. $VER="2.0";
  11. @fldnms= ("mail_from","mail_to","cc","date","time_zone","file","sbj","txt");
  12. my $fields= 0;
  13. my $base_q= "";
  14. my $mail_count= 0;
  15. $opt_user= $opt_password= "";
  16. $opt_socket= "/tmp/mysql.sock";
  17. $opt_port= 3306;
  18. $opt_db="mail";
  19. $opt_table="my_mail";
  20. $opt_help=$opt_count=0;
  21. $opt_thread= 0;
  22. $opt_host= "";
  23. $opt_message_id= 0;
  24. GetOptions("help","count","port=i","db=s","table=s","host=s","password=s",
  25. "user=s","socket=s", "thread","message_id") || usage();
  26. if ($opt_host eq '')
  27. {
  28. $opt_host = "localhost";
  29. }
  30. if ($opt_help || !$ARGV[0])
  31. {
  32. usage();
  33. }
  34. ####
  35. #### Connect and parsing the query to MySQL
  36. ####
  37. $dbh= DBI->connect("DBI:mysql:$opt_db:$opt_host:port=$opt_port:mysql_socket=$opt_socket", $opt_user,$opt_password, { PrintError => 0})
  38. || die $DBI::errstr;
  39. main();
  40. ####
  41. #### main
  42. ####
  43. sub main
  44. {
  45. my ($row, $val, $q, $mail, $sth);
  46. if ($opt_count)
  47. {
  48. count_mails();
  49. }
  50. $base_q= "SELECT ";
  51. foreach $val (@fldnms)
  52. {
  53. if (!$fields)
  54. {
  55. $base_q.= "$val";
  56. }
  57. else
  58. {
  59. $base_q.= ",$val";
  60. }
  61. $fields++;
  62. }
  63. $base_q.= ",message_id" if ($opt_thread || $opt_message_id);
  64. $base_q.= " FROM $opt_table";
  65. $q= " WHERE $ARGV[0]";
  66. $sth= $dbh->prepare($base_q . $q);
  67. if (!$sth->execute)
  68. {
  69. print "$DBI::errstr\n";
  70. $sth->finish;
  71. die;
  72. }
  73. for (; ($row= $sth->fetchrow_arrayref); $mail_count++)
  74. {
  75. for ($i= 0; $i < $fields; $i++)
  76. {
  77. if ($opt_message_id)
  78. {
  79. $mail[$fields][$mail_count]= $row->[$fields];
  80. $mail[$fields][$mail_count].= "\nNumber of Replies: " . get_nr_replies($row->[$fields]);
  81. }
  82. $mail[$i][$mail_count]= $row->[$i];
  83. }
  84. if ($opt_thread)
  85. {
  86. get_mail_by_message_id($row->[$fields], $mail);
  87. }
  88. }
  89. print_mails($mail);
  90. }
  91. ####
  92. #### Function, which fetches mail by searching in-reply-to with
  93. #### a given message_id. Saves the value (mail) in mail variable.
  94. #### Returns the message id of the mail found and searches again
  95. #### and saves, until no more mails are found with that message_id.
  96. ####
  97. sub get_mail_by_message_id
  98. {
  99. my ($message_id, $mail)= @_;
  100. my ($q, $query, $i, $row, $sth);
  101. $q= " WHERE in_reply_to = \"$message_id\"";
  102. $query= $base_q . $q;
  103. $sth= $dbh->prepare($query);
  104. if (!$sth->execute)
  105. {
  106. print "QUERY: $query\n$DBI::errstr\n";
  107. $sth->finish;
  108. die;
  109. }
  110. while (($row= $sth->fetchrow_arrayref))
  111. {
  112. $mail_count++;
  113. for ($i= 0; $i < $fields; $i++)
  114. {
  115. if ($opt_message_id)
  116. {
  117. $mail[$fields][$mail_count]= $row->[$fields];
  118. $mail[$fields][$mail_count].= "\nNumber of Replies: " . get_nr_replies($row->[$fields]);
  119. }
  120. $mail[$i][$mail_count]= $row->[$i];
  121. }
  122. $new_message_id= $row->[$fields];
  123. if (defined($new_message_id) && length($new_message_id))
  124. {
  125. get_mail_by_message_id($new_message_id, $mail);
  126. }
  127. }
  128. return;
  129. }
  130. ####
  131. #### Get number of replies for a given message_id
  132. ####
  133. sub get_nr_replies
  134. {
  135. my ($message_id)= @_;
  136. my ($sth, $sth2, $q, $row, $row2, $nr_replies);
  137. $nr_replies= 0;
  138. $q= "SELECT COUNT(*) FROM my_mail WHERE in_reply_to=\"$message_id\"";
  139. $sth= $dbh->prepare($q);
  140. if (!$sth->execute)
  141. {
  142. print "QUERY: $q\n$DBI::errstr\n";
  143. $sth->finish;
  144. die;
  145. }
  146. while (($row= $sth->fetchrow_arrayref))
  147. {
  148. if (($nr_replies= $row->[0]))
  149. {
  150. $q= "SELECT message_id FROM my_mail WHERE in_reply_to=\"$message_id\"";
  151. $sth2= $dbh->prepare($q);
  152. if (!$sth2->execute)
  153. {
  154. print "QUERY: $q\n$DBI::errstr\n";
  155. $sth->finish;
  156. die;
  157. }
  158. while (($row2= $sth2->fetchrow_arrayref))
  159. {
  160. # There may be several replies to the same mail. Also the
  161. # replies to the 'parent' mail may contain several replies
  162. # and so on. Thus we need to calculate it recursively.
  163. $nr_replies+= get_nr_replies($row2->[0]);
  164. }
  165. }
  166. return $nr_replies;
  167. }
  168. }
  169. ####
  170. #### Print mails
  171. ####
  172. sub print_mails
  173. {
  174. my ($mail)= @_;
  175. my ($i);
  176. for ($i=0; $mail[0][$i]; $i++)
  177. {
  178. print "#" x 33;
  179. print " " . ($i+1) . ". Mail ";
  180. print "#" x 33;
  181. print "\n";
  182. if ($opt_message_id)
  183. {
  184. print "Msg ID: $mail[$fields][$i]\n";
  185. }
  186. print "From: $mail[0][$i]\n";
  187. print "To: $mail[1][$i]\n";
  188. print "Cc:" . (defined($mail[2][$i]) ? $mail[2][$i] : "") . "\n";
  189. print "Date: $mail[3][$i]\n";
  190. print "Timezone: $mail[4][$i]\n";
  191. print "File: $mail[5][$i]\n";
  192. print "Subject: $mail[6][$i]\n";
  193. print "Message:\n$mail[7][$i]\n";
  194. }
  195. print "#" x 20;
  196. print " Summary: ";
  197. if ($i == 1)
  198. {
  199. print "$i Mail ";
  200. print "matches the query ";
  201. }
  202. else
  203. {
  204. print "$i Mails ";
  205. print "match the query ";
  206. }
  207. print "#" x 20;
  208. print "\n";
  209. }
  210. ####
  211. #### Count mails that matches the query, but don't show them
  212. ####
  213. sub count_mails
  214. {
  215. my ($sth);
  216. $sth= $dbh->prepare("select count(*) from $opt_table where $ARGV[0]");
  217. if (!$sth->execute)
  218. {
  219. print "$DBI::errstr\n";
  220. $sth->finish;
  221. die;
  222. }
  223. while (($row= $sth->fetchrow_arrayref))
  224. {
  225. $mail_count= $row->[0];
  226. }
  227. if ($mail_count == 1)
  228. {
  229. print "$mail_count Mail matches the query.\n";
  230. }
  231. else
  232. {
  233. print "$mail_count Mails match the query.\n";
  234. }
  235. exit;
  236. }
  237. ####
  238. #### Usage
  239. ####
  240. sub usage
  241. {
  242. print <<EOF;
  243. pmail version $VER by Jani Tolonen
  244. Usage: pmail [options] "SQL where clause"
  245. Options:
  246. --help show this help
  247. --count Shows how many mails matches the query, but not the mails.
  248. --db= database to use (Default: $opt_db)
  249. --host= Hostname which to connect (Default: $opt_host)
  250. --socket= Unix socket to be used for connection (Default: $opt_socket)
  251. --password= Password to use for mysql
  252. --user= User to be used for mysql connection, if not current user
  253. --port= mysql port to be used (Default: $opt_port)
  254. --thread Will search for possible replies to emails found by the search
  255. criteria. Replies, if found, will be displayed right after the
  256. original mail.
  257. --message_id Display message_id on top of each mail. Useful when searching
  258. email threads with --thread. On the second line is the number
  259. of replies to the same thread, starting counting from that
  260. mail (excluding possible parent mails).
  261. "SQL where clause" is the end of the select clause,
  262. where the condition is expressed. The result will
  263. be the mail(s) that matches the condition and
  264. will be displayed with the fields:
  265. - From
  266. - To
  267. - Cc
  268. - Date
  269. - Timezone
  270. - File (Where from the current mail was loaded into the database)
  271. - Subject
  272. - Message text
  273. The field names that can be used in the where clause are:
  274. Field Type
  275. - message_id varchar(255) # Use with --thread and --message_id
  276. - in_reply_to varchar(255) # Internally used by --thread
  277. - mail_from varchar(120)
  278. - date datetime
  279. - sbj varchar(200)
  280. - txt mediumtext
  281. - cc text
  282. - mail_to text
  283. - time_zone varchar(6)
  284. - reply varchar(120)
  285. - file varchar(32)
  286. - hash int(11)
  287. An example of pmail:
  288. pmail "txt like '%libmysql.dll%' and sbj like '%delphi%'"
  289. NOTE: the txt field is NOT case sensitive!
  290. EOF
  291. exit(0);
  292. }