File: list.c

package info (click to toggle)
sn 0.3.8-12
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 976 kB
  • sloc: ansic: 9,255; sh: 467; makefile: 210
file content (139 lines) | stat: -rw-r--r-- 3,143 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * This file is part of the sn package.
 * Distribution of sn is covered by the GNU GPL. See file COPYING.
 * Copyright � 1998-2000 Harold Tay.
 * Copyright � 2000- Patrik R�dman.
 */

/*
 * Functions for the NNTP LIST command and its variants.
 * Assumes args[0] is "LIST", and args[1] is not null.
 */

#include <fnmatch.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "config.h"
#include "art.h"
#include "group.h"
#include "args.h"
#include "snntpd.h"
#include "key.h"
#include <out.h>
#include <wildmat.h>

static const char ver_ctrl_id[] = "$Id: list.c 29 2004-04-24 23:02:38Z patrik $";

/* Same as LIST but may have an optional wildmat */

static void listactive (void)
{
   struct group g;
   struct key *kp;
   int i, j;
   char *group;

   args_write(1, "215 list follows\r\n");

   for_each_key(i, j, kp)
   {
      group = KEY(kp);
      if (!args[1] || !args[2] || wildmat(group, args[2]))
         if (0 == group_info(group, &g))
            args_write(1, "%s %d %d %s\r\n", group, g.last, g.first, g.nopost ? "n" : "y");
   }

   args_write(1, ".\r\n");
}

/* Display format of overview database */

static void listoverviewfmt (void)
{
   args_write(1, "215 ok\r\n");
   args_write(1, "Subject:\r\n"
              "From:\r\n"
              "Date:\r\n"
              "Message-ID:\r\n" "References:\r\n" "Bytes:\r\n" "Lines:\r\n" "Xref:full\r\n.\r\n");
}

static void listnewsgroups (void)
{
   args_write(1, "215 Here you go\r\n");

   if (nr_keys > 0)
   {
      char *group;
      int i, j;
      struct key *kp;

      for_each_key(i, j, kp)
      {
         group = KEY(kp);
         if (!args[2] || wildmat(group, args[2]))
         {
            char buf[128];

            if (topline(group, ".info", buf, sizeof (buf)) <= 0)
               *buf = '\0';
            args_write(1, "%s %s\r\n", group, buf);
         }
      }
   }
   args_write(1, ".\r\n");
}

/* ZB was here */

static void listdistribpats (void)
{
   args_write(1, "215 ok\r\n");
   args_write(1, ".\r\n");
}

void do_list (void)
{
   if (args[1])
   {
      if (0 == strcasecmp(args[1], "active"))
         listactive();
      else if (0 == strcasecmp(args[1], "newsgroups"))
         listnewsgroups();
      else if (0 == strcasecmp(args[1], "overview.fmt"))
         listoverviewfmt();
      else if (0 == strcasecmp(args[1], "distrib.pats"))
         listdistribpats();
      else
         args_write(1, "503 \"LIST %s\" command not implemented\r\n", args[1]);
   }
   else
      listactive();
}

void do_listgroup (void)
{
   struct article bogus;
   int i;

   if (args[1])
   {
      if (alltolower(args[1]) > GROUPNAMELEN || make_current(args[1]))
      {
         args_write(1, "411 No such group\r\n");
         return;
      }
   }
   else if (!currentgroup)
   {
      args_write(1, "412 No group selected\r\n");
      return;
   }
   args_write(1, "211 Article numbers follow\r\n");
   for (i = currentinfo.first; i <= currentinfo.last; i++)
      if (0 == art_gimme(currentgroup, i, &bogus))
         writef(1, "%d\r\n", i);
   args_write(1, ".\r\n");
   currentserial = currentinfo.first;
}