1
/****************************************************************************\
2
* opts.c - sprio command line option parsing
3
*****************************************************************************
4
* Copyright (C) 2009 Lawrence Livermore National Security.
5
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
6
* Written by Don Lipari <lipari1@llnl.gov>
7
* CODE-OCEC-09-009. All rights reserved.
9
* This file is part of SLURM, a resource management program.
10
* For details, see <https://computing.llnl.gov/linux/slurm/>.
11
* Please also read the included file: DISCLAIMER.
13
* SLURM is free software; you can redistribute it and/or modify it under
14
* the terms of the GNU General Public License as published by the Free
15
* Software Foundation; either version 2 of the License, or (at your option)
18
* In addition, as a special exception, the copyright holders give permission
19
* to link the code of portions of this program with the OpenSSL library under
20
* certain conditions as described in each individual source file, and
21
* distribute linked combinations including the two. You must obey the GNU
22
* General Public License in all respects for all of the code used other than
23
* OpenSSL. If you modify file(s) with this exception, you may extend this
24
* exception to your version of the file(s), but you are not obligated to do
25
* so. If you do not wish to do so, delete this exception statement from your
26
* version. If you delete this exception statement from all source files in
27
* the program, then also delete it here.
29
* SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
30
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
31
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
34
* You should have received a copy of the GNU General Public License along
35
* with SLURM; if not, write to the Free Software Foundation, Inc.,
36
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
37
\*****************************************************************************/
50
# include "src/common/getopt.h"
56
#include <sys/types.h>
59
#include "src/common/read_config.h"
60
#include "src/common/uid.h"
61
#include "src/common/xstring.h"
62
#include "src/sprio/sprio.h"
64
/* getopt_long options, integers but not characters */
65
#define OPT_LONG_HELP 0x100
66
#define OPT_LONG_USAGE 0x101
69
static List _build_job_list( char* str );
70
static List _build_user_list( char* str );
71
static char *_get_prefix(char *token);
72
static void _help( void );
73
static void _parse_token( char *token, char *field, int *field_size,
74
bool *right_justify, char **suffix);
75
static void _print_options( void );
76
static void _print_version( void );
77
static void _usage( void );
83
parse_command_line( int argc, char* argv[] )
87
static struct option long_options[] = {
88
{"noheader", no_argument, 0, 'h'},
89
{"jobs", optional_argument, 0, 'j'},
90
{"long", no_argument, 0, 'l'},
91
{"norm", no_argument, 0, 'n'},
92
{"format", required_argument, 0, 'o'},
93
{"user", required_argument, 0, 'u'},
94
{"users", required_argument, 0, 'u'},
95
{"verbose", no_argument, 0, 'v'},
96
{"version", no_argument, 0, 'V'},
97
{"weights", no_argument, 0, 'w'},
98
{"help", no_argument, 0, OPT_LONG_HELP},
99
{"usage", no_argument, 0, OPT_LONG_USAGE},
103
while((opt_char = getopt_long(argc, argv, "hj::lno:u:vVw",
104
long_options, &option_index)) != -1) {
107
fprintf(stderr, "Try \"sprio --help\" "
108
"for more information\n");
111
params.no_header = true;
115
params.jobs = xstrdup(optarg);
116
params.job_list = _build_job_list(params.jobs);
118
params.job_flag = true;
121
params.long_list = true;
124
params.normalized = true;
127
xfree(params.format);
128
params.format = xstrdup(optarg);
132
params.users = xstrdup(optarg);
133
params.user_list = _build_user_list(params.users);
142
params.weights = true;
154
if (params.job_flag) {
155
params.jobs = xstrdup(argv[optind++]);
156
params.job_list = _build_job_list(params.jobs);
159
error("Unrecognized option: %s",argv[optind]);
165
if ( params.verbose )
170
* parse_format - Take the user's format specification and use it to build
171
* build the format specifications (internalize it to print.c data
173
* IN format - user's format specification
174
* RET zero or error code
176
extern int parse_format( char* format )
180
char *prefix = NULL, *suffix = NULL, *token = NULL;
181
char *tmp_char = NULL, *tmp_format = NULL;
184
if (format == NULL) {
185
error ("Format option lacks specification.");
189
params.format_list = list_create( NULL );
190
if ((prefix = _get_prefix(format))) {
191
job_format_add_prefix( params.format_list, 0, 0, prefix);
194
field_size = strlen( format );
195
tmp_format = xmalloc( field_size + 1 );
196
strcpy( tmp_format, format );
198
token = strtok_r( tmp_format, "%", &tmp_char);
199
if (token && (format[0] != '%')) /* toss header */
200
token = strtok_r( NULL, "%", &tmp_char );
202
_parse_token( token, field, &field_size, &right_justify,
205
job_format_add_age_priority_normalized(params.format_list,
209
else if (field[0] == 'A')
210
job_format_add_age_priority_weighted(params.format_list,
214
else if (field[0] == 'f')
215
job_format_add_fs_priority_normalized(params.format_list,
219
else if (field[0] == 'F')
220
job_format_add_fs_priority_weighted(params.format_list,
224
else if (field[0] == 'i')
225
job_format_add_job_id(params.format_list,
229
else if (field[0] == 'j')
230
job_format_add_js_priority_normalized(params.format_list,
234
else if (field[0] == 'J')
235
job_format_add_js_priority_weighted(params.format_list,
239
else if (field[0] == 'N')
240
job_format_add_job_nice(params.format_list,
244
else if (field[0] == 'p')
245
job_format_add_part_priority_normalized(params.format_list,
249
else if (field[0] == 'P')
250
job_format_add_part_priority_weighted(params.format_list,
254
else if (field[0] == 'q')
255
job_format_add_qos_priority_normalized(params.format_list,
259
else if (field[0] == 'Q')
260
job_format_add_qos_priority_weighted(params.format_list,
264
else if (field[0] == 'u')
265
job_format_add_user_name(params.format_list,
269
else if (field[0] == 'y')
270
job_format_add_job_priority_normalized(params.format_list,
274
else if (field[0] == 'Y')
275
job_format_add_job_priority_weighted(params.format_list,
280
error( "Invalid job format specification: %c",
283
token = strtok_r( NULL, "%", &tmp_char);
287
return SLURM_SUCCESS;
290
/* Take a format specification and copy out it's prefix
291
* IN/OUT token - input specification, everything before "%" is removed
292
* RET - everything before "%" in the token
295
_get_prefix( char *token )
302
pos = strchr(token, (int) '%');
303
if (pos == NULL) /* everything is prefix */
304
return xstrdup(token);
305
if (pos == token) /* no prefix */
308
pos[0] = '\0'; /* some prefix */
309
prefix = xstrdup(token);
311
memmove(token, pos, (strlen(pos)+1));
315
/* Take a format specification and break it into its components
316
* IN token - input specification without leading "%", eg. ".5u"
317
* OUT field - the letter code for the data type
318
* OUT field_size - byte count
319
* OUT right_justify - true of field to be right justified
320
* OUT suffix - string containing everthing after the field specification
323
_parse_token( char *token, char *field, int *field_size, bool *right_justify,
328
assert (token != NULL);
330
if (token[i] == '.') {
331
*right_justify = true;
334
*right_justify = false;
337
while ((token[i] >= '0') && (token[i] <= '9'))
338
*field_size = (*field_size * 10) + (token[i++] - '0');
340
field[0] = token[i++];
342
*suffix = xstrdup(&token[i]);
345
/* print the parameters specified */
349
ListIterator iterator;
354
printf( "-----------------------------\n" );
355
printf( "format = %s\n", params.format );
356
printf( "job_flag = %d\n", params.job_flag );
357
printf( "jobs = %s\n", params.jobs );
358
printf( "users = %s\n", params.users );
359
printf( "verbose = %d\n", params.verbose );
361
if ((params.verbose > 1) && params.job_list) {
363
iterator = list_iterator_create( params.job_list );
364
while ( (job_id = list_next( iterator )) ) {
365
printf( "job_list[%d] = %u\n", i++, *job_id);
367
list_iterator_destroy( iterator );
370
if ((params.verbose > 1) && params.user_list) {
372
iterator = list_iterator_create( params.user_list );
373
while ( (user = list_next( iterator )) ) {
374
printf( "user_list[%d] = %u\n", i++, *user);
376
list_iterator_destroy( iterator );
379
printf( "-----------------------------\n\n\n" );
384
* _build_job_list- build a list of job_ids
385
* IN str - comma separated list of job_ids
386
* RET List of job_ids (uint32_t)
389
_build_job_list( char* str )
392
char *job = NULL, *tmp_char = NULL, *my_job_list = NULL;
394
uint32_t *job_id = NULL;
398
my_list = list_create( NULL );
399
my_job_list = xstrdup( str );
400
job = strtok_r( my_job_list, ",", &tmp_char );
403
i = strtol( job, (char **) NULL, 10 );
405
error( "Invalid job id: %s", job );
408
job_id = xmalloc( sizeof( uint32_t ) );
409
*job_id = (uint32_t) i;
410
list_append( my_list, job_id );
411
job = strtok_r (NULL, ",", &tmp_char);
417
* _build_user_list- build a list of UIDs
418
* IN str - comma separated list of user names
419
* RET List of UIDs (uint32_t)
422
_build_user_list( char* str )
426
char *tmp_char = NULL, *my_user_list = NULL;
427
uid_t uid = (uid_t) 0;
432
my_list = list_create( NULL );
433
my_user_list = xstrdup( str );
434
user = strtok_r( my_user_list, ",", &tmp_char );
436
if (uid_from_string (user, &uid) < 0) {
437
error( "Invalid user: %s\n", user);
439
uint32_t *u_tmp = xmalloc( sizeof( uint32_t ));
440
*u_tmp = (uint32_t) uid;
441
list_append( my_list, u_tmp );
443
user = strtok_r (NULL, ",", &tmp_char);
448
static void _print_version(void)
450
printf("%s %s\n", PACKAGE, SLURM_VERSION);
453
static void _usage(void)
455
printf("Usage: sprio [-j jid[s]] [-u user_name[s]] [-o format] [--usage] [-hlnvVw]\n");
458
static void _help(void)
461
Usage: sprio [OPTIONS]\n\
462
-h, --noheader no headers on output\n\
463
-j, --jobs comma separated list of jobs\n\
464
to view, default is all\n\
465
-l, --long long report\n\
466
-n, --norm display normalized values\n\
467
-o, --format=format format specification\n\
468
-u, --user=user_name comma separated list of users to view\n\
469
-v, --verbose verbosity level\n\
470
-V, --version output version information and exit\n\
471
-w, --weights show the weights for each priority factor\n\
473
--help show this help message\n\
474
--usage display a brief summary of sprio options\n");