1+ #include "arg_flags.h"
2+ #include "arg_handlers.h"
3+ #include <stdio.h>
4+ #include <stdlib.h>
5+ #include <string.h>
6+
7+ static int handle_flag (int argc , char * argv [], int * i , int * target , int expected_value , int disallowed_value );
8+ static int handle_string (int argc , char * argv [], int * i , char * target , size_t max_length );
9+ static int parse_string (int argc , char * argv [], int * i , const char * * target );
10+ static int is_known_flag (const char * arg );
11+
12+
13+ int handle_encrypt (int argc , char * argv [], int * i , cli_args_t * opts )
14+ {
15+ return handle_flag (argc , argv , i , & opts -> encrypt_mode , 1 , -1 );
16+ }
17+
18+ int handle_decrypt (int argc , char * argv [], int * i , cli_args_t * opts )
19+ {
20+ return handle_flag (argc , argv , i , & opts -> encrypt_mode , 0 , -1 );
21+ }
22+
23+ int handle_key (int argc , char * argv [], int * i , cli_args_t * opts )
24+ {
25+ return handle_string (argc , argv , i , opts -> key , KEY_LENGTH );
26+ }
27+
28+ int handle_input (int argc , char * argv [], int * i , cli_args_t * opts )
29+ {
30+ return handle_string (argc , argv , i , opts -> input_path , PATH_LENGTH );
31+ }
32+
33+ int handle_output (int argc , char * argv [], int * i , cli_args_t * opts )
34+ {
35+ return handle_string (argc , argv , i , opts -> output_path , PATH_LENGTH );
36+ }
37+
38+ static int handle_flag (int argc , char * argv [], int * i , int * target , int expected_value , int disallowed_value )
39+ {
40+ (void )argc ;
41+
42+ const char * flag_name = argv [* i ];
43+
44+ if (* target != disallowed_value )
45+ {
46+ fprintf (stderr , "Error: duplicate or conflicting %s flag.\n" , flag_name );
47+ return -1 ;
48+ }
49+
50+ * target = expected_value ;
51+ return 0 ;
52+ }
53+
54+ static int handle_string (int argc , char * argv [], int * i , char * target , size_t max_length )
55+ {
56+ const char * flag_name = argv [* i ];
57+
58+ if (target [0 ])
59+ {
60+ fprintf (stderr , "Error: duplicate %s flag.\n" , flag_name );
61+ return -1 ;
62+ }
63+
64+ const char * arg ;
65+ if (parse_string (argc , argv , i , & arg ) != 0 || is_known_flag (arg ))
66+ {
67+ fprintf (stderr , "Error: %s requires a value.\n" , flag_name );
68+ return -1 ;
69+ }
70+
71+ if (strlen (arg ) >= max_length )
72+ {
73+ fprintf (stderr , "Error: value for %s is too long (max %zu characters).\n" , flag_name , max_length - 1 );
74+ return -1 ;
75+ }
76+
77+ strncpy (target , arg , max_length );
78+ target [max_length - 1 ] = '\0' ;
79+
80+ return 0 ;
81+ }
82+
83+ static int parse_string (int argc , char * argv [], int * i , const char * * arg )
84+ {
85+ if (++ (* i ) >= argc || argv [* i ][0 ] == '\0' )
86+ {
87+ return -1 ;
88+ }
89+
90+ * arg = argv [* i ];
91+ return 0 ;
92+ }
93+
94+ static const char * known_flags [] = {
95+ FLAG_ENCRYPT ,
96+ FLAG_DECRYPT ,
97+ FLAG_GENERATE_KEY ,
98+ FLAG_KEY ,
99+ FLAG_INPUT ,
100+ FLAG_OUTPUT ,
101+ NULL
102+ };
103+
104+ static int is_known_flag (const char * arg )
105+ {
106+ for (int i = 0 ; known_flags [i ] != NULL ; ++ i )
107+ {
108+ if (strcmp (arg , known_flags [i ]) == 0 )
109+ {
110+ return 1 ;
111+ }
112+ }
113+
114+ return 0 ;
115+ }
0 commit comments