-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.c
2253 lines (2116 loc) · 67.2 KB
/
main.c
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sfuncs.h"
#include "parser.h"
#include "extprgfuncs.h"
#include "dbexchange.h"
#include "main.h"
int isquiet = 0, isallyes = 0, isallno = 0, isforce = 0;
int docmd(char **cmdntsa, int offset)
{
int i;
for (i=offset;cmdntsa[i]!=NULL;i++)
{
if (cmdntsa[i][0] != '-') break;
if (streq_i(cmdntsa[i],"-q"))
{
isquiet = 1;
}
else if (streq_i(cmdntsa[i],"-y"))
{
if (isallno == 0) isallyes = 1;
else isallno = 0;
}
else if (streq_i(cmdntsa[i],"-n"))
{
if (isallyes == 0) isallno = 1;
else isallyes = 0;
}
else if (streq_i(cmdntsa[i],"-f"))
{
isforce = 1;
}
}
if (cmdntsa[i] == NULL) return 0;
if (streq_i(cmdntsa[i],"test"))
{
if (cmdntsa[i+1] == NULL)
{
fprintf(stderr, "Error: Test object not specified! Test what?\n");
return 1;
}
else if (streq_i(cmdntsa[i+1], "parser"))
{
if (cmdntsa[i+2] == NULL)
{
fprintf(stderr, "Error: Feed File not specified! Test parser with what?\n");
return 1;
}
return testparser(cmdntsa[i+2]);
}
else if (streq_i(cmdntsa[i+1], "download_parser"))
{
if (cmdntsa[i+2] == NULL)
{
fprintf(stderr, "Error: URL not specified! Test download_parser with what?\n");
return 1;
}
return testdlparser(cmdntsa[i+2]);
}
else if (streq_i(cmdntsa[i+1], "database"))
{
/* Open then close the database */
return testdb();
}
else if (streq_i(cmdntsa[i+1], "downloader"))
{
if (cmdntsa[i+2] == NULL)
{
fprintf(stderr, "Error: URL not specified! Test downloader with what?\n");
return 1;
}
return testdownload(cmdntsa[i+2]);
}
else
{
fprintf(stderr, "Error: Unknown Test '%s'!\n", cmdntsa[i+1]);
return 1;
}
}
else if (streq_i(cmdntsa[i], "subscribe"))
{
if (cmdntsa[i+1] == NULL)
{
fprintf(stderr, "Error: Feed URL specified! Subscribe to what?\n");
return 1;
}
else if (cmdntsa[i+2] == NULL)
{
fprintf(stderr, "Error: 'Download' command missing!\n");
return 1;
}
else if (streq_i(cmdntsa[i+2], "download") == 0)
{
fprintf(stderr, "Error: Invalid sub command - you must specify the download type!\n");
return 1;
}
else if (cmdntsa[i+3] == NULL)
{
fprintf(stderr, "Error: 'Download' type missing! Download which items?\n");
return 1;
}
else if (streq_i(cmdntsa[i+3],"none"))
{
/* Just subscribe */
return dosubscribe(cmdntsa[i+1], DLCODE_NONE);
}
else if (streq_i(cmdntsa[i+3],"latest"))
{
/* Subscribe and download the latest */
return dosubscribe(cmdntsa[i+1], DLCODE_LATEST);
}
else if (streq_i(cmdntsa[i+3],"all") || streq_i(cmdntsa[i+3],"new"))
{
/* Subscribe and download everything */
return dosubscribe(cmdntsa[i+1], DLCODE_ALL);
}
else
{
fprintf(stderr, "Error: Invalid 'Download' type - must be 'none', 'latest' or 'all'!\n");
return 1;
}
}
else if (streq_i(cmdntsa[i], "configure") || streq_i(cmdntsa[i], "config"))
{
if (cmdntsa[i+1] == NULL)
{
fprintf(stderr, "Error: Configuration command not specified! Set or View?\n");
return 1;
}
else if (streq_i(cmdntsa[i+1], "set"))
{
if (cmdntsa[i+2] == NULL)
{
fprintf(stderr, "Error: Setting not specified! Set what?\n");
return 1;
}
else if ((cmdntsa[i+3] == NULL) || ((streq_(cmdntsa[i+3],"=")) && (cmdntsa[i+4] == NULL)))
{
fprintf(stderr, "Error: Value of Setting not specified! Set %s to what?\n", cmdntsa[i+2]);
return 1;
}
else
{
if (streq_(cmdntsa[i+3],"="))
{
return configuresetting(cmdntsa[i+2],cmdntsa[i+4]);
}
else
{
return configuresetting(cmdntsa[i+2],cmdntsa[i+3]);
}
}
}
else if (streq_i(cmdntsa[i+1], "view"))
{
if (cmdntsa[i+2] == NULL)
{
/* View all settings */
if (opendb(0) == 0)
{
fprintf(stderr, "Error: Could not open database!\n");
return 2;
}
if (writecsview(NULL)==0)
{
fprintf(stderr, "Error: Could not list settings!\n");
closedb();
return 3;
}
if (closedb() == 0)
{
fprintf(stderr, "Error: Could not close database!\n");
closedb();
return 2;
}
else return 0;
}
else
{
/* View specified setting */
if (opendb(0) == 0)
{
fprintf(stderr, "Error: Could not open database!\n");
return 2;
}
if (writecsview(cmdntsa[i+2])==0)
{
fprintf(stderr, "Error: Could not show setting!\n");
closedb();
return 3;
}
if (closedb() == 0)
{
fprintf(stderr, "Error: Could not close database!\n");
closedb();
return 2;
}
else return 0;
}
}
else
{
fprintf(stderr, "Error: Unknown Configuration Command '%s'!\n", cmdntsa[i+1]);
return 1;
}
}
else if (streq_i(cmdntsa[i], "download") || streq_i(cmdntsa[i], "dl"))
{
if (cmdntsa[i+1] == NULL)
{
fprintf(stderr, "Error: Download subcommand not specified - see 'help download' for available\nsubcommands. Download what?\n");
return 1;
}
else if (streq_i(cmdntsa[i+1], "channel"))
{
if (cmdntsa[i+2] == NULL)
{
fprintf(stderr,"Error: Channel Identifier not specified - see 'help download channel' for\ndetails. Download from which channel?\n");
return 1;
}
else
{
if (cmdntsa[i+3] == NULL)
{
fprintf(stderr, "Error: Subcommand not specified - see 'help download channel' for details.\nDownload what?\n");
return 1;
}
else if (streq_i(cmdntsa[i+3], "none"))
{
//Download None - do nothing!
return 0;
}
else if (streq_i(cmdntsa[i+3], "latest"))
{
//Download Latest
return downloadchannellatest(cmdntsa[i+2]);
}
else if (streq_i(cmdntsa[i+3], "all"))
{
//Download All
return downloadchannelall(cmdntsa[i+2]);
}
else if (streq_i(cmdntsa[i+3], "item"))
{
//Download a specific item:
if (cmdntsa[i+4] == NULL)
{
fprintf(stderr, "Error: Subcommand not specified - see 'help download channel item' for details.\nDownload which item?\n");
return 1;
}
else
{
//Download item cmdntsa[i+4]
return downloadchannelitem(cmdntsa[i+2], cmdntsa[i+4]);
}//Offset 4 Download Channel (chanid) Item __
}
else
{
fprintf(stderr,"Error: Unknown subcommand '%s' - see 'help download channel' for details.\n", cmdntsa[i+2]);
return 1;
}//Offset 3 Download Channel (chanid) __
}//Offset 2 Download Channel __
}
else
{
fprintf(stderr,"Error: Unknown subcommand '%s' - see 'help download' for details.\n", cmdntsa[i+1]);
return 1;
}//Offset 1 Download __
}
else if (streq_i(cmdntsa[i], "update"))
{
if (cmdntsa[i+1] == NULL)
{
fprintf(stderr, "Error: Update subcommand not specified - see 'help Update' for available\nsubcommands. Update what?\n");
return 1;
}
else if (streq_i(cmdntsa[i+1], "channel"))
{
if (cmdntsa[i+2] == NULL)
{
fprintf(stderr,"Error: Channel Identifier not specified - see 'help update channel' for\ndetails. Update which channel?\n");
return 1;
}
else
{
if (cmdntsa[i+3] == NULL)
{
fprintf(stderr, "Error: Subcommand not specified - see 'help update channel' for details.\nUpdate channel and do what?\n");
return 1;
}
else if (streq_i(cmdntsa[i+3], "download"))
{
if (cmdntsa[i+4] == NULL)
{
fprintf(stderr, "Error: Subcommand not specified - see 'help update channel download' for\ndetails. Update channel and download what?\n");
return 1;
}
else if (streq_i(cmdntsa[i+4],"none"))
{
/* Update and download none */
return updatechanneldownloadnone(cmdntsa[i+2]);
}
else if (streq_i(cmdntsa[i+4],"latest"))
{
/* Update and download latest */
return updatechanneldownloadlatest(cmdntsa[i+2]);
}
else if (streq_i(cmdntsa[i+4],"new"))
{
/* Update and download new */
return updatechanneldownloadnew(cmdntsa[i+2]);
}
else if (streq_i(cmdntsa[i+4],"all"))
{
/* Update and download all */
return updatechanneldownloadall(cmdntsa[i+2]);
}
else
{
fprintf(stderr,"Error: Unknown subcommand '%s' - see 'help update channel download'\nfor details.\n", cmdntsa[i+4]);
return 1;
} /* Offset 4 Update Channel ___ Download __ */
}
else
{
fprintf(stderr,"Error: Unknown subcommand '%s' - see 'help update channel' for details.\n", cmdntsa[i+3]);
return 1;
} /* Offset 3 Update Channel ___ __ */
} /* Offset 2 Update Channel __ */
}
else
{
fprintf(stderr,"Error: Unknown subcommand '%s' - see 'help update' for details.\n", cmdntsa[i+1]);
return 1;
} /* Offset 1 Update __ */
}
else if (streq_i(cmdntsa[i], "list"))
{
if (cmdntsa[i+1] == NULL)
{
fprintf(stderr, "Error: List subcommand not specified - see 'help list' for available\nsubcommands. List what?\n");
return 1;
}
else if (streq_i(cmdntsa[i+1], "channels"))
{
/* List all channels */
if (opendb(0) == 0)
{
fprintf(stderr, "Error: Could not open database!\n");
closedb();
return 2;
}
if (listallchannels() == 1)
{
closedb();
return 0;
}
closedb();
return 2;
}
else if (streq_i(cmdntsa[i+1], "channel"))
{
/* List channel <channel identifier> */
if (cmdntsa[i+2] == NULL)
{
fprintf(stderr,"Error: Channel Identifier not specified - see 'help list channel' for details.\nList which channel?");
return 1;
}
else
{
/* list channel n - do this in a subfunction */
return listchannelarg(cmdntsa[i+2]);
}
}
else if (streq_i(cmdntsa[i+1], "items"))
{
/* List items in channel <channel identifier> */
if (cmdntsa[i+2] == NULL)
{
fprintf(stderr,"Error: Subcommand 'in' not specified - see 'help list items' for details.\n");
return 1;
}
else if (streq_i(cmdntsa[i+2], "in"))
{
if (cmdntsa[i+3] == NULL)
{
fprintf(stderr,"Error: Subcommand 'channel' not specified - see 'help list items' for details. List items in where?\n");
return 1;
}
else if (streq_i(cmdntsa[i+3],"channel"))
{
if (cmdntsa[i+4] == NULL)
{
fprintf(stderr,"Error: Channel Identifier not specified - see 'help list items' for details.\nList items in which channel?\n");
return 1;
}
else
{
/* List Items in channel n - deal with this in a subfunction */
return listitemsinchannelarg(cmdntsa[i+4]);
}
}
else
{
fprintf(stderr,"Error: Unknown subcommand '%s' - should be 'channel'. See 'help list items'\nfor details. List items in where?\n",cmdntsa[i+3]);
return 1;
}
}
else
{
fprintf(stderr,"Error: Unknown subcommand '%s' - should be 'in'. See 'help list items' for\ndetails.\n",cmdntsa[i+2]);
return 1;
}
}
else if (streq_i(cmdntsa[i+1], "item"))
{
/* List item <item identifier> in channel <channel identifier> */
if (cmdntsa[i+2] == NULL)
{
fprintf(stderr,"Error: Item Identifier not specified - see 'help list item' for details. List\nwhich item?\n");
return 1;
}
else
{
if (cmdntsa[i+3] == NULL)
{
fprintf(stderr, "Error: Subcommand 'in' not specified - see 'help list item' for details.\n");
return 1;
}
else if (streq_i(cmdntsa[i+3],"in"))
{
if (cmdntsa[i+4] == NULL)
{
fprintf(stderr, "Error: Subcommand 'channel' not specified - see 'help list item' for details.\nList item in where?\n");
return 1;
}
else if (streq_i(cmdntsa[i+4],"channel"))
{
if (cmdntsa[i+5] == NULL)
{
fprintf(stderr, "Error: Channel Identifier not specified - see 'help list item' for details.\nList item in where?\n");
return 1;
}
else
{
/* List item x in y - Deal with this in a subfunction */
return listitemarginchannelarg(cmdntsa[i+2],cmdntsa[i+5]);
}
}
else
{
fprintf(stderr, "Error: Unknown subcommand '%s', subcommand 'channel' expected - see\n'help list item' for details. List item in where?\n", cmdntsa[i+4]);
return 1;
}
}
else
{
fprintf(stderr, "Error: Unknown subcommand '%s', subcommand 'in' expected - see 'help list item'\nfor details.\n",cmdntsa[i+3]);
return 1;
}
}
}
else
{
fprintf(stderr,"Error: Unknown subcommand '%s' - see 'help list' for details.\n", cmdntsa[i+1]);
return 1;
}
}
else if (streq_i(cmdntsa[i], "help"))
{
if (cmdntsa[i+1] == NULL || (cmdntsa[i+2] == NULL && streq_i(cmdntsa[i+1], "help")))
{
printf("Use the command 'help <command>' where '<command>' is a command you want to\nunderstand.\n");
printf("Commands:\n*\ttest\n*\tconfigure\n*\tsubscribe\n*\tlist\n*\tdownload\n*\thelp\n");
return 0;
}
else if (streq_i(cmdntsa[i+1], "test"))
{
if (cmdntsa[i+2] == NULL)
{
printf("Test:\n Tests a function of the program.\nSubcommands of Test:\n*\tparser\n*\tdatabase\n*\tdownloader\n*\tdownload_parser\n");
return 0;
}
else if (streq_i(cmdntsa[i+2], "parser"))
{
printf("Test Parser:\n Tests the parser of RSS files. Use the command as 'test parser <feed file>',\nwhere <feed file> is the file containing the RSS feed to parse. The file must\nbe locally accessible, not a URL.\n");
return 0;
}
else if (streq_i(cmdntsa[i+2], "download_parser"))
{
printf("Test Parser:\n Tests the downloader and parser of RSS files. Use the command as\n 'test parser <URL>', where <URL> is the url of the file containing the RSS\n feed to parse.\n");
return 0;
}
else if (streq_i(cmdntsa[i+2], "downloader"))
{
printf("Test Downloader:\n Tests the downloader of files. Use the command as 'test downloader <URL>',\n where <URL> is the URL of the file download.\n");
return 0;
}
else if (streq_i(cmdntsa[i+2], "database"))
{
printf("Test Database:\n Tests the database connectivity. This command has no arguments.\n");
return 0;
}
else
{
fprintf(stderr, "Error: Unknown Help Test command '%s', use 'help test' for commands.\n", cmdntsa[i+2]);
}
} /* End of Help Test */
else if (streq_i(cmdntsa[i+1], "configure") || streq_i(cmdntsa[i+1], "config"))
{
if (cmdntsa[i+2] == NULL)
{
printf("Configure:\n Configures a setting of the program.\nSubcommands of Configure:\n*\tset\n*\tview\n");
return 0;
}
else if (streq_i(cmdntsa[i+2], "set"))
{
if (cmdntsa[i+3] == NULL)
{
printf("Set Configuration:\n Sets a setting in the configuration. Use the command as\n 'configure set <setting> = <value>', where <setting> is the setting to\n change and <value> is the value to give it.\n");
printf("Possible Settings:\n*\tPODCAST_DIR\n*\tDOWNLOADER\n*\tMEDIA_PLAYER\n*\tDIR_SEPARATOR\n");
return 0;
}
else if (streq_i(cmdntsa[i+3],"LAST OPENED"))
{
printf("LAST OPENED:\n This is the last time the Database was opened for modification. This setting\n should not be altered manually!\n");
return 0;
}
else if (streq_i(cmdntsa[i+3],"PODCAST_DIR"))
{
printf("PODCAST_DIR:\n This is full path of the directory in which the downloaded podcasts should be\n saved. The user running the program MUST have write permissions for\n this directory.\n");
return 0;
}
else if (streq_i(cmdntsa[i+3], "DOWNLOADER"))
{
printf("DOWNLOADER:\n This is the full command that will download files for the program. This must\n include the full path of the program used, in addition to specifying\n the URL from which to download as !U, the filename to save the file as !F and\n the full path in which to save this file as !P.\n");
return 0;
}
else if (streq_i(cmdntsa[i+3], "MEDIA_PLAYER"))
{
printf("MEDIA_PLAYER:\n This is the full command that will play files for the program. This must\n include the full path of the program used, in addition to specifying\n the filename to play as !F and the full path of the file as !P.\n");
return 0;
}
else if (streq_i(cmdntsa[i+3], "DIR_SEPARATOR"))
{
printf("DIR_SEPARATOR:\n This is the character that is used as a directory separator on your system.\n For UNIX-like systems such as GNU Linux, this is '/', whereas for Windows\n and similar systems, this is '\\'.\n");
return 0;
}
else
{
fprintf(stderr, "Error: Unknown Setting '%s'\n",cmdntsa[i+3]);
return 1;
}
}
else if (streq_i(cmdntsa[i+2], "view"))
{
if (cmdntsa[i+3] == NULL)
{
printf("View Configuration:\n Views a setting in the configuration. Use the command as\n'configure view <setting>' where <setting> is the setting of which to see the\nvalue.\n");
printf("Possible Settings:\n*\tPODCAST_DIR\n*\tDOWNLOADER\n*\tMEDIA_PLAYER\n*\tDIR_SEPARATOR\n");
return 0;
}
else if (streq_i(cmdntsa[i+3],"LAST OPENED"))
{
printf("LAST OPENED:\n This is the last time the Database was opened for modification.\n This setting should not be altered manually!\n");
return 0;
}
else if (streq_i(cmdntsa[i+3],"PODCAST_DIR"))
{
printf("PODCAST_DIR:\n This is full path of the directory in which the downloaded podcasts should be\n saved. The user running the program MUST have write permissions for\n this directory.\n");
return 0;
}
else if (streq_i(cmdntsa[i+3], "DOWNLOADER"))
{
printf("DOWNLOADER:\n This is the full command that will download files for the program. This must\n include the full path of the program used, in addition to specifying\n the URL from which to download as !U, the filename to save the file as !F and\n the full path in which to save this file as !P.\n");
return 0;
}
else if (streq_i(cmdntsa[i+3], "MEDIA_PLAYER"))
{
printf("MEDIA_PLAYER:\n This is the full command that will play files for the program. This must\n include the full path of the program used, in addition to specifying\n the filename to play as !F and the full path of the file as !P.\n");
return 0;
}
else if (streq_i(cmdntsa[i+3], "DIR_SEPARATOR"))
{
printf("DIR_SEPARATOR:\n This is the character that is used as a directory separator on your system.\n For UNIX-like systems such as GNU Linux, this is '/', whereas for Windows\n and similar systems, this is '\\'.\n");
return 0;
}
else
{
fprintf(stderr, "Error: Unknown Setting '%s'\n",cmdntsa[i+3]);
return 1;
}
}
else
{
fprintf(stderr, "Error: Unknown Help Configure command '%s', use 'help configure' for commands.\n", cmdntsa[i+2]);
return 1;
}
} /* End of Help Configure */
else if (streq_i(cmdntsa[i+1], "subscribe"))
{
if (cmdntsa[i+2] == NULL)
{
printf("Subscribe:\n Subscribes to a podcast feed. Use the command as:\n 'subscribe <URL of feed> download <download type>'.\n The following download types are available:\n*\tnone\n*\tlatest\n*\tall\n For help on these, use the command:\n 'help subscribe download <download type>'.\n");
return 0;
}
else if (streq_i(cmdntsa[i+2],"download") == 0)
{
fprintf(stderr, "Error: Unknown Help Subscribe command '%s', must be 'download'.\n", cmdntsa[i+2]);
return 1;
}
else if (cmdntsa[i+3] == NULL)
{
printf("Subscribe:\n Subscribes to a podcast feed. Use the command as:\n 'subscribe <URL of feed> download <download type>'.\n The following download types are available:\n*\tnone\n*\tlatest\n*\tall\n For help on these, use the command:\n 'help subscribe download <download type>'.\n");
return 0;
}
else if (streq_i(cmdntsa[i+3],"none"))
{
printf("Subscribe and Download None:\n This command subscribes to a podcast feed but does not download any of the\n items. Use this command as 'subscribe <feed URL> download none'.\n");
return 0;
}
else if (streq_i(cmdntsa[i+3],"latest"))
{
printf("Subscribe and Download Latest:\n This command subscribes to a podcast feed and downloads the item with the\n latest Publication Date (not necessarily the last that was added). Use this\n command as 'subscribe <feed URL> download latest'.\n");
return 0;
}
else if (streq_i(cmdntsa[i+3],"all") || streq_i(cmdntsa[i+3],"new"))
{
printf("Subscribe and Download All:\n This command subscribes to a podcast feed and downloads all the items that\n are on it. Use this command as 'subscribe <feed URL> download all'.\n");
return 0;
}
else
{
fprintf(stderr, "Error: Unknown Download Type '%s' - see 'help subscribe' for the list.\n", cmdntsa[i+3]);
return 1;
}
} /* End of Help Subscribe */
else if (streq_i(cmdntsa[i+1], "list"))
{
if (cmdntsa[i+2] == NULL)
{
printf("List:\n List channels or items in a channel.\n Subcommands:\n*\tchannels\n*\tchannel\n*\titems\n*\titem\n");
return 0;
}
else if (streq_i(cmdntsa[i+2],"channels"))
{
printf("List Channels:\n Lists all the channels to which you have subscribed. This subcommand takes\nno arguments.\n");
return 0;
}
else if (streq_i(cmdntsa[i+2],"channel"))
{
printf("List Channel:\n This lists the details of a specific channel. The syntax of this command is\n'list channel <channel identifier>', where '<channel identifier>' is the\nidentifier of the channel. This can be:\n*\tThe Channel Title (if this begins with an exclamation mark ('!'),\n\tdouble the exclamation mark to escape it; e.g. '!title' becomes\n\t'!!title').\n*\tAn exclamation mark ('!') followed by the number of the channel (as\n\twritten next to the channel title in the output of the 'list channels'\n\tcommand), e.g. '!1'.\n*\tThe special code '!LATEST', meaning the channel to have been last\n\tupdated.\n*\tThe special code '!ALL', meaning to list all channels providing details\n\ton each.\n");
return 0;
}
else if (streq_i(cmdntsa[i+2],"items"))
{
printf("List Items In Channel:\n This lists the items in a specific channel. The syntax of this command is\n'list items in channel <channel identifier>', where '<channel identifier>' is\nthe identifier of the channel containing the items. This can be:\n*\tThe Channel Title (if this begins with an exclamation mark ('!'),\n\tdouble the exclamation mark to escape it; e.g. '!title' becomes\n\t'!!title').\n*\tAn exclamation mark ('!') followed by the number of the channel (as\n\twritten next to the channel title in the output of the 'list channels'\n\tcommand), e.g. '!1'.\n*\tThe special code '!LATEST', meaning the channel to have been last\n\tupdated.\n*\tThe special code '!ALL', meaning to list all channels providing details\n\ton each.\n");
return 0;
}
else if (streq_i(cmdntsa[i+2],"item"))
{
printf("List (Specific) Item In Channel:\n This lists the details of a specific item in a specific channel. The syntax\nof this command is:\n'list item <item identifier> in channel <channel identifier>', where\n'<item identifier>' is the identifier of the item on which to provide details\nand '<channel identifier>' is the identifier of the channel containing the\nitems. The Item Identifier can be:\n*\tThe Item Title (if it begins with an exclamation mark ('!'),\n\twrite the exclamation mark twice to escape it; e.g. '!title' becomes\n\t'!!title').\n*\tAn exclamation mark ('!') followed by the number of the item (as written\n\tnext to the title of the item in the output of the\n\t'list items in channel <channel identifier>' command), e.g. '!1'\n*\tThe special code '!LATEST', meaning the item in the channel with the\n\tmost recent publication date.\n*\tThe special code '!DOWNLOADED', meaning to list details on all the\n\titems in the specified channel(s) that have been downloaded.\n*\tThe special code '!NOTDOWNLOADED', meaning to list details on all the\n\titems in the specified channel(s) that have not yet been downloaded.\n*\tThe special code '!ALL', meaning to list all items in the specified\n\tchannel(s) and provide details on each.\n The output from the last three special codes will be really long and should\nbe piped into a file or a program to break it down.\n The Channel Identifier can be:\n*\tThe Channel Title (if this begins with an exclamation mark ('!'),\n\tdouble the exclamation mark to escape it; e.g. '!title' becomes\n\t'!!title').\n*\tAn exclamation mark ('!') followed by the number of the channel (as\n\twritten next to the channel title in the output of the 'list channels'\n\tcommand), e.g. '!1'.\n*\tThe special code '!LATEST', meaning the channel to have been last\n\tupdated.\n*\tThe special code '!ALL', meaning to list all channels providing\n\tdetails on each. This code can only be used with item identifiers of\n\t'!DOWNLOADED', '!NOTDOWNLOADED' and '!ALL'.\n");
return 0;
}
else
{
fprintf(stderr,"Error: Invalid Help List Command!\n");
return 1;
}
} /* End of Help List */
else if (streq_i(cmdntsa[i+1], "download"))
{
if (cmdntsa[i+2] == NULL)
{
printf("Download:\n Download items.\n Subcommands:\n*\tchannel\n");
return 0;
}
else if (streq_i(cmdntsa[i+2], "channel"))
{
if (cmdntsa[i+3] == NULL)
{
printf("Download Channel:\n Download items in a subscribed channel. The syntax of this command is\n 'download channel <channel identifier> <subcommand>', where\n '<channel identifier>' is the identifier of the channel. This can be:\n*\tThe Channel Title (if this begins with an exclamation mark ('!'),\n\tdouble the exclamation mark to escape it; e.g. '!title' becomes\n\t('!!title').\n*\tAn exclamation mark ('!') followed by the number of the channel (as\n\twritten next to the channel title in the output of the 'list channels'\n\tcommand), e.g. '!1'.\n*\tThe special code '!LATEST', meaning the last channel to have been\n\tupdated.\n*\tThe special code '!ALL', meaning all channels.\n Subcommands:\n*\tnone\n*\tlatest\n*\tall\n*\titem\n");
return 0;
}
else if (streq_i(cmdntsa[i+3],"none"))
{
printf("Download Channel None:\n This is a dummy operation that does nothing. The syntax of this command is\n 'download channel <channel identifier> none', where '<channel identifier>' is\n the identifier of the channel. This can be:\n*\tThe Channel Title (if this begins with an exclamation mark ('!'),\n\tdouble the exclamation mark to escape it; e.g. '!title' becomes\n\t'!!title').\n*\tAn exclamation mark ('!') followed by the number of the channel (as\n\twritten next to the channel title in the output of the 'list channels'\n\tcommand), e.g. '!1'.\n*\tThe special code '!LATEST', meaning the channel to have been last\n\tupdated.\n*\tThe special code '!ALL', meaning to download from all channels.\n");
return 0;
}
else if (streq_i(cmdntsa[i+3],"latest"))
{
printf("Download Channel Latest:\n Download the latest item in the specified channel. The syntax of this\n command is 'download channel <channel identifier> latest', where\n '<channel identifier>' is the identifier of the channel. This can be:\n*\tThe Channel Title (if this begins with an exclamation mark ('!'),\n\tdouble the exclamation mark to escape it; e.g. '!title' becomes\n\t'!!title').\n*\tAn exclamation mark ('!') followed by the number of the channel (as\n\twritten next to the channel title in the output of the 'list channels'\n\tcommand), e.g. '!1'.\n*\tThe special code '!LATEST', meaning the channel to have been last\n\tupdated.\n*\tThe special code '!ALL', meaning to download from all channels.\n");
return 0;
}
else if (streq_i(cmdntsa[i+3],"all"))
{
printf("Download Channel All:\n Download all the undownloaded items in the specified channel. The syntax of\n this command is 'download channel <channel identifier> all', where\n '<channel identifier>' is the identifier of the channel. This can be:\n*\tThe Channel Title (if this begins with an exclamation mark ('!'),\n\tdouble the exclamation mark to escape it; e.g. '!title' becomes\n\t'!!title').\n*\tAn exclamation mark ('!') followed by the number of the channel (as\n\twritten next to the channel title in the output of the 'list channels'\n\tcommand), e.g. '!1'.\n*\tThe special code '!LATEST', meaning the channel to have been last\n\tupdated.\n*\tThe special code '!ALL', meaning to download from all channels.\n");
return 0;
}
else if (streq_i(cmdntsa[i+3],"item"))
{
printf("Download Channel Item:\n Download the specified item in the specified channel. The syntax of this\n command is 'download channel <channel identifier> item <item identifier>',\n where '<channel identifier>' is the identifier of the channel and\n '<item identifier>' is the identifier of the item. The channel identifier\n can be:\n*\tThe Channel Title (if this begins with an exclamation mark ('!'),\n\tdouble the exclamation mark to escape it; e.g. '!title' becomes\n\t'!!title').\n*\tAn exclamation mark ('!') followed by the number of the channel (as\n\twritten next to the channel title in the output of the 'list channels'\n\tcommand), e.g. '!1'.\n*\tThe special code '!LATEST', meaning the channel to have been last\n\tupdated.\n*\tThe special code '!ALL', meaning to download from all channels.\n");
printf(" The item identifier can be:\n*\tThe Item Title (if this begins with an exclamation mark ('!'),\n\tdouble the exclamation mark to escape it; e.g. '!title' becomes\n\t'!!title').\n*\tAn exclamation mark ('!') followed by the number of the channel (as\n\twritten next to the channel title in the output of the\n\t'list channels' command), e.g. '!1'.\n*\tThe special code '!LATEST', meaning the latest item in the specified\n\tchannel.\n*\tThe special code '!NOTDOWNLOADED', meaning to download every item in\n\tthe specified channel that has yet to be downloaded\n*\tThe special code '!DOWNLOADED', meaning to re-download every\n\tpreviously-downloaded item in the specified channel (not\n\trecommended).\n*\tThe special code '!ALL', meaning to download every item from the\n\tspecified channle, no matter whether or not it's been previously\n\tdownloaded.\n");
return 0;
}
else
{
fprintf(stderr, "Error: Invalid Help Download Channel Command!\n");
return 1;
}
} /* End of Help Download Channel */
else
{
fprintf(stderr, "Error: Invalid Help Download Command!\n");
return 1;
}
} /* End of Help Download */
else if (streq_i(cmdntsa[i+1], "help") && cmdntsa[i+2] != NULL)
{
fprintf(stderr, "Error: Too many help commands! Hey, no recursing!\n");
return 1;
}
else
{
fprintf(stderr, "Error: Unknown Help command '%s', use 'help' for command list.\n",cmdntsa[i+1]);
return 1;
}
}
else
{
fprintf(stderr, "Error: Unknown Command '%s'! Use the 'help' command for a command\nlist.\n", cmdntsa[i]);
return 1;
}
return 1;
}
int main(int argc, char *argv[])
{
if (argc < 2 || streq_i(argv[1],"--help"))
{
printf("Usage:\n\t%s [-q] [{-y | -n}] [-f] <command> [<subcommand>] [<arguments>]\n", argv[0]);
printf("Flags:\n\t-q\tQuiet Mode\n\t-y\tAnswer 'Yes' to everything\n\t-n\tAnswer 'No' to everything\n\t-f\tForce command\n");
printf("Commands:\n*\ttest\n*\tconfigure\n*\tsubscribe\n*\tlist\n*\thelp\n");
printf("Test Usage: %s test parser <feed file>\n Where <feed file> is the file containing the RSS feed.\n", argv[0]);
return 1;
}
#ifdef DEBUG
printf("%d, %d\n",streq_i("title","titlE"), endwith_("abc]]>","]]>"));
#endif
/*return testparser(argv[1]);*/
return docmd(argv, 1);
}
int testparser(char *rssfile)
{
FILE *feedfile = fopen(rssfile,"r");
if (feedfile == NULL)
{
fprintf(stderr,"Error opening file %s\n", rssfile);
return 2;
}
int parserret = parsersstoll(feedfile);
fclose(feedfile);
if (parserret == 0)
{
fprintf(stderr,"Error reading file!\n");
return 3;
}
else if (parserret == -1)
{
fprintf(stderr,"Memory Error!\n");
return 4;
}
else if (parserret == -2)
{
fprintf(stderr,"Error! File is not RSS!\n");
return 5;
}
else
{
printf("File:\n");
listdata();
destroyitems();
destroychannels();
destroycategories();
return 0;
}
}
int testdb()
{
closedb();
if (opendb(1))
{
printf("Database Opened and Checked Successfully!\n");
if (closedb())
{
printf("Database Closed Successfully!\n");
return 0;
}
fprintf(stderr, "Error: Database Failed to close!\n");
closedb();
return 2;
}
fprintf(stderr, "Error: Database Failed to open and check!\n");
return 2;
}
int testdownload(char *url)
{
if (dodownload(url, ".", "1.txt") == 0)
{
fprintf(stderr, "Error: Test download failed.\n");
return 3;
}
printf("Test Download successful - file is \"1.txt\".\n");
return 0;
}
int configuresetting(char *setting, char *value)
{
int settingnum = 0;
char asetting[256] = "";
if (setting == NULL || value == NULL) return 1;
if (streq_i(setting, "LAST OPENED")) settingnum = 1;
else if (streq_i(setting, "PODCAST_DIR")) settingnum = 2;
else if (streq_i(setting, "DOWNLOADER")) settingnum = 3;
else if (streq_i(setting, "MEDIA_PLAYER")) settingnum = 4;
else if (streq_i(setting, "DIR_SEPARATOR")) settingnum = 5;
else
{
fprintf(stderr, "Error: Unknown setting '%s'!\n", setting);
return 1;
}
if (opendb(1) == 0)
{
fprintf(stderr, "Error: Database failed to open!\n");
return 2;
}
switch (settingnum)
{
case 1:
strcpy(asetting, "LAST OPENED");
break;
case 2:
strcpy(asetting, "PODCAST_DIR");
break;
case 3:
strcpy(asetting, "DOWNLOADER");
break;
case 4:
strcpy(asetting, "MEDIA_PLAYER");
break;
case 5:
strcpy(asetting, "DIR_SEPARATOR");
break;
}
/* Set setting to value here */
if (preparecsstatement(asetting) == 0)
{
fprintf(stderr, "Error: Failed prepare SQL for setting adjustment.\n");
closedb();
return 3;
}
if (setconfigsetting(asetting, value) == 0)
{
fprintf(stderr, "Error: Failed execute SQL to adjust setting.\n");
closedb();
return 4;
}
if (closedb() == 0)
{
fprintf(stderr, "Error: Failed to close Database\n");
closedb();
return 2;
}
printf("Successfully set %s to '%s'.\n", asetting, value);
return 0;
}
int testdlparser(char *url)
{
if (dodownload(url, ".", "1.xml") == 0)
{
fprintf(stderr, "Error: Test download failed.\n");
return 3;
}
char rssfile[2048] = "";
char *pdir;
pdir = getsettingdata("PODCAST_DIR");
if (pdir == NULL)
{
fprintf(stderr, "Error: Could not find Podcast Directory.\n");
return 2;
}
else if (pdir[0] == 0)
{
fprintf(stderr, "Error: Podcast Directory not set!\n");
free(pdir);
return 2;
}
char *dirsep;
dirsep = getsettingdata("DIR_SEPARATOR");
if (dirsep == NULL)
{
fprintf(stderr, "Error: Could not find Directory Separator.\n");
free(pdir);
return 2;
}
else if (dirsep[0] == 0)
{
fprintf(stderr, "Error: Directory Separator not set!\n");
free(pdir);
free(dirsep);
return 2;
}
strcpy(rssfile,pdir);
strcat(rssfile,dirsep);
strcat(rssfile,"1.xml");
free(pdir);
free(dirsep);
closedb();
FILE *feedfile = fopen(rssfile,"r");
if (feedfile == NULL)
{
fprintf(stderr,"Error opening file '%s'\n", rssfile);
return 2;
}
int parserret = parsersstoll(feedfile);
fclose(feedfile);
if (parserret == 0)
{
fprintf(stderr,"Error reading file!\n");
return 3;
}
else if (parserret == -1)
{
fprintf(stderr,"Memory Error!\n");
return 4;
}
else if (parserret == -2)
{
fprintf(stderr,"Error! File is not RSS!\n");
return 5;
}
else
{
printf("File:\n");
listdata();
destroyitems();
destroychannels();
destroycategories();
return 0;
}
}
int dosubscribe(char *url, int dlcode)
{
if (getchanidfromurl(url) != 0)
{
fprintf(stderr, "Already subscribed to channel!\n");
return 8;
}
if (dodownload(url, ".", "new_feed.xml") == 0)
{
fprintf(stderr, "Error: Feed download failed.\n");
closedb();
return 3;
}
char *pdir;
char *feedfn;
pdir = getsettingdata("PODCAST_DIR");
if (pdir == NULL)
{
fprintf(stderr, "Error: Could not find Podcast Directory.\n");
closedb();