1 /*
2  * ckey.c
3  *
4  * implements channel key list (so you don't have to remember them!)
5  *
6  * written by Joshua J. Drake
7  */
8 
9 #include "ckey.h"
10 #include "channels.h"
11 #include "ninja.h"
12 #include "dma.h"
13 #include "list.h"
14 #include "ircaux.h"
15 #include "output.h"
16 
17 /* global variables */
18 CKey *ckey_list = (CKey *) NULL;	/* channel key list */
19 
20 /*
21  * gets the key to a channel from the ckey list.
22  *
23  * returns a pointer to the actual key string.
24  */
25 u_char *
get_ckey(u_char * chan)26 get_ckey(u_char *chan)
27 {
28    CKey *tmp;
29 
30    /* no ckeys, no business */
31    if (!ckey_list)
32      return empty_string;
33 
34    /* if we can't find a ckey for the specified channel, return "" */
35    if ((tmp = (CKey *) find_in_list((List **)&ckey_list, chan, 0)) == NULL)
36      return empty_string;
37    return tmp->key;
38 }
39 
40 
41 /*
42  * free all data associated with a ckey list entry
43  */
44 void
free_ckey(tmp)45 free_ckey(tmp)
46     CKey **tmp;
47 {
48    CKey *ok = *tmp;
49 
50    dma_Free(&(ok->key));
51    dma_Free(&(ok->channel));
52    dma_Free(&ok);
53 }
54 
55 /*
56  * adds a ckey to the ckey list, unless of course one already exists.
57  * in that case, it replaces it with the key specified.
58  */
59 void
add_ckey(chan,key)60 add_ckey(chan, key)
61    u_char *chan, *key;
62 {
63    CKey *tmp, *new;
64 
65    /* if either argument is empty, never mind */
66    if (key == NULL || chan == NULL)
67      return;
68 
69    /* try to remove the ckey from the list. (fails if it doesn't exist) */
70    if ((tmp = (CKey *) remove_from_list((List **)&ckey_list, chan)) != NULL)
71      free_ckey(&tmp);
72 
73    /* okay, so now there's no ckey for that channel even if there was one.. so we make a new entry */
74    new = (CKey *) dma_Malloc(sizeof(CKey));
75    dma_strcpy(&new->key, key);
76    dma_strcpy(&new->channel, chan);
77 
78    /* add the new entry to the list */
79    add_to_list((List **)&ckey_list, (List *)new);
80 
81    /* save the list every time one is added.. (good for when you core dump) */
82    if (!qflag)
83      (void)save_ckeys(1);
84 }
85 
86 /*
87  * saves the ckey list to NINJA_CKEY_FILE for later retreival (when you start ninja again)
88  */
89 int
save_ckeys(quiet)90 save_ckeys(quiet)
91     int quiet;
92 {
93    u_char *fullname = NULL;
94    FILE *fdesc;
95    CKey *tmp;
96    int count = 0;
97 
98    fullname = expand_twiddle(NINJA_CKEY_FILE);
99    fdesc = fopen(fullname, "w");
100    if (fdesc == (FILE *)NULL)
101      {
102         put_error("Cannot write channel key list: %s", strerror(errno));
103 	dma_Free(&fullname);
104         return 0;
105      }
106    dma_Free(&fullname);
107 
108    /* run through the list, printing a line for each, format: <chan> <key>\n */
109    for (tmp = ckey_list; tmp; tmp = tmp->next)
110      {
111         fprintf(fdesc, "%s %s\n", tmp->channel, tmp->key);
112         count++;
113      }
114    fclose(fdesc);
115 
116    /* if we're not being quiet, and there were keys saved, then tell the user about it */
117    if (!quiet && count)
118      put_info("Saved %d channel key%s...", count, count != 1 ? UP("s") : empty_string);
119    return count;
120 }
121 
122 /*
123  * load the ckey list back into memory from disk.
124  */
125 void
load_ckeys(void)126 load_ckeys(void)
127 {
128    u_char *fullname = NULL, tmpinbuf[1024], *tibptr, *chan, *key;
129    FILE *fdesc;
130 
131    fullname = expand_twiddle(NINJA_CKEY_FILE);
132    fdesc = fopen(fullname, "r");
133    if (fdesc == (FILE *) NULL)
134      {
135         /* we're not gonna print this anymore
136 	put_info("Cannot read Channel Key list..");
137 	 */
138 	dma_Free(&fullname);
139         return;
140      }
141    dma_Free(&fullname);
142 
143    /* read the list. */
144    memset(tmpinbuf, 0, sizeof(tmpinbuf));
145    while (fgets(tmpinbuf, sizeof(tmpinbuf)-1, fdesc))
146      {
147 	/* strip the new line/carriage return */
148 	tibptr = my_rindex(tmpinbuf, '\n');
149 	if (tibptr)
150 	  *tibptr = '\0';
151 	tibptr = my_rindex(tmpinbuf, '\r');
152 	if (tibptr)
153 	  *tibptr = '\0';
154 
155 	/* extract the channel/key */
156         tibptr = tmpinbuf;
157         chan = next_arg(tibptr, &tibptr);
158         key = next_arg(tibptr, &tibptr);
159 
160 	/* add it to the list */
161         add_ckey(chan, key);
162 	memset(tmpinbuf, 0, sizeof(tmpinbuf));
163      }
164    fclose(fdesc);
165 }
166 
167 
168 void
free_ckeylist(void)169 free_ckeylist(void)
170 {
171    CKey *tmp, *next;
172 
173    for (tmp = ckey_list; tmp; tmp = next)
174      {
175 	next = tmp->next;
176 	free_ckey(&tmp);
177      }
178 }
179