1 /*
2  * SNOOPY LOGGER
3  *
4  * File: snoopy/datasource/cmdline.c
5  *
6  * Copyright (c) 2014-2015 Bostjan Skufca <bostjan@a2o.si>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  */
22 
23 
24 
25 /*
26  * Includes order: from local to global
27  */
28 #include "cmdline.h"
29 
30 #include "snoopy.h"
31 #include "inputdatastorage.h"
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 
37 
38 
39 /*
40  * SNOOPY DATA SOURCE: cmdline
41  *
42  * Description:
43  *     Returns command line of current process.
44  *
45  * Params:
46  *     result: pointer to string, to write result into
47  *     arg:    (ignored)
48  *
49  * Return:
50  *     number of characters in the returned string, or SNOOPY_DATASOURCE_FAILURE
51  */
snoopy_datasource_cmdline(char * const result,char const * const arg)52 int snoopy_datasource_cmdline (char * const result, char const * const arg)
53 {
54     char   *cmdLine = NULL;
55     int     cmdLineArgCount;
56     int     cmdLineSizeSum;   // Size sum of all arguments and spaces in between
57     int     cmdLineSizeRet;   // Size that will be returned
58     int     n;
59     const snoopy_inputdatastorage_t * snoopy_inputdatastorage;
60 
61     /* Get argument data of execv/e() call */
62     snoopy_inputdatastorage = snoopy_inputdatastorage_get();
63 
64     /* Count number of arguments */
65     for (cmdLineArgCount=0 ; *(snoopy_inputdatastorage->argv+cmdLineArgCount) != (char *) 0 ; cmdLineArgCount++);
66 
67     /* Calculate memory requirement for cmdLine */
68     cmdLineSizeSum = 1;
69     for (int i=0 ; i<cmdLineArgCount ; i++) {
70         /* Argument length + space */
71         cmdLineSizeSum += strlen(snoopy_inputdatastorage->argv[i]) + 1;
72     }
73     /* Do not substract the +1 from the last iteration - the last character (most likely a space) will be converted to \0 */
74     if (cmdLineSizeSum > SNOOPY_DATASOURCE_MESSAGE_MAX_SIZE) {
75         cmdLineSizeRet = SNOOPY_DATASOURCE_MESSAGE_MAX_SIZE;
76     } else {
77         cmdLineSizeRet = cmdLineSizeSum;
78     }
79 
80     /* Initialize cmdLine */
81     cmdLine    = malloc(cmdLineSizeRet);
82     cmdLine[0] = '\0';
83 
84     n = 0;
85     for (int i=0 ; i<cmdLineArgCount ; i++) {
86         n += snprintf(cmdLine+n, cmdLineSizeRet-n, "%s", snoopy_inputdatastorage->argv[i]);
87 
88         if (n < cmdLineSizeRet) {
89             cmdLine[n] = ' ';
90             n++;
91         }
92 
93         if (n >= cmdLineSizeRet) {
94             n = cmdLineSizeRet;
95             break;
96         }
97     }
98 
99     /* Conclude the string - add \0 at the end */
100     if (n > 0) n--;
101     cmdLine[n] = '\0';
102 
103     /* Copy the result to the string pointed by return pointer */
104     snprintf(result, SNOOPY_DATASOURCE_MESSAGE_MAX_SIZE, "%s", cmdLine);
105 
106     free(cmdLine);
107     return cmdLineSizeRet;
108 }
109