1 /* $Id: filechan.c 6135 2003-01-19 01:15:40Z rra $
3 ** An InterNetNews channel process that splits a funnel entry into
4 ** separate files. Originally from Robert Elz <kre@munnari.oz.au>.
13 #include "inn/innconf.h"
14 #include "inn/messages.h"
21 main(int ac, char *av[])
29 const char *Directory;
37 /* First thing, set up our identity. */
38 message_program_name = "filechan";
41 if (!innconf_read(NULL))
44 Directory = innconf->pathoutgoing;
50 while ((i = getopt(ac, av, "d:f:m:p:")) != EOF)
59 Fields = atoi(optarg);
66 if ((F = fopen(optarg, "w")) == NULL)
67 sysdie("cannot fopen %s", optarg);
68 fprintf(F, "%ld\n", (long)getpid());
69 if (ferror(F) || fclose(F) == EOF)
70 sysdie("cannot fclose %s", optarg);
74 /* Move, and get owner of current directory. */
75 if (chdir(Directory) < 0)
76 sysdie("cannot chdir to %s", Directory);
77 if (stat(".", &Sb) < 0)
78 sysdie("cannot stat %s", Directory);
83 while (fgets(buff, sizeof buff, stdin) != NULL) {
84 if ((p = strchr(buff, '\n')) != NULL)
87 /* Skip the right number of leading fields. */
88 for (i = Fields, p = buff; *p; p++)
89 if (*p == ' ' && --i <= 0)
92 /* Nothing to write. Probably shouldn't happen. */
95 /* Add a newline, get the length of all leading fields. */
99 /* Rest of the line is space-separated list of filenames. */
100 for (; *p; p = next) {
101 /* Skip whitespace, get next word. */
104 for (next = p; *next && *next != ' '; next++)
111 fd = open(p, O_CREAT | O_WRONLY | O_APPEND, BATCHFILE_MODE);
113 /* Try to lock it and set the ownership right. */
114 inn_lock_file(fd, INN_LOCK_WRITE, true);
115 if (myuid == 0 && uid != 0)
118 /* Just in case, seek to the end. */
119 lseek(fd, 0, SEEK_END);
122 if (write(fd, buff, i) != i)
123 sysdie("write failed");