CodeCompass

Форк
0
/
ldlogger-logger.c 
269 строк · 5.1 Кб
1
#include <sys/types.h>
2
#include <sys/stat.h>
3
#include <sys/file.h>
4
#include <fcntl.h>
5
#include <unistd.h>
6
#include <stdio.h>
7
#include <stdint.h>
8
#include <string.h>
9
#include <stdlib.h>
10
#include <ctype.h>
11

12
#include "ldlogger-tool.h"
13
#include "ldlogger-util.h"
14
#include "ldlogger-hooks.h"
15

16
static char* createJsonCommandString(const LoggerVector* args_)
17
{
18
  size_t cmdSize = 0;
19
  char* cmd;
20
  char* currEnd;
21
  size_t i;
22

23
  /* Calculate */
24
  for (i = 0; i < args_->size; ++i)
25
  {
26
    cmdSize += strlen((const char*) args_->data[i]);
27
  }
28

29
  /* The final size is:
30
       The overall size of command * 2 for escaping +
31
       args_->size character for word separator +
32
       args_->size * 2 character for word escaping ('"'' chars) separator +
33
       1 byte character trailing null
34
  */
35
  cmdSize = (cmdSize * 2) + (args_->size * 3) + 1;
36
  cmd = (char*) malloc(sizeof(char) * cmdSize);
37
  if (!cmd)
38
  {
39
    return NULL;
40
  }
41

42
  currEnd = cmd;
43
  currEnd += strlen(shellEscapeStr((const char*) args_->data[0], currEnd));
44
  for (i = 1; i < args_->size; ++i)
45
  {
46
    *currEnd = ' ';
47
    ++currEnd;
48
    currEnd += strlen(shellEscapeStr((const char*) args_->data[i], currEnd));
49
  }
50

51
  *currEnd = '\0';
52
  return cmd;
53
}
54

55
static void writeAction(
56
  FILE* stream_,
57
  char const* wd_,
58
  const LoggerAction* action_,
59
  int* entryCount_)
60
{
61
  size_t i;
62
  char* command;
63

64
  command = createJsonCommandString(&action_->arguments);
65
  if (!command)
66
  {
67
    return;
68
  }
69

70
  for (i = 0; i < action_->sources.size; ++i)
71
  {
72
    if (++(*entryCount_) > 1)
73
    {
74
      fprintf(stream_, "\t,\n");
75
    }
76

77
    fprintf(stream_,
78
      "\t{\n" \
79
      "\t\t\"directory\": \"%s\",\n" \
80
      "\t\t\"command\": \"%s\",\n" \
81
      "\t\t\"file\": \"%s\"\n" \
82
      "\t}\n",
83
      wd_,                                    /* directory */
84
      command,                                /* command */
85
      (const char*) action_->sources.data[i]  /* file */
86
    );
87
  }
88

89
  free(command);
90
}
91

92
static void writeActions(FILE* stream_, char const* wd_, const LoggerVector* actions_)
93
{
94
  size_t i;
95
  long fsize;
96
  int entryCount = 0;
97

98
  if (actions_->size <= 0)
99
  {
100
    return;
101
  }
102

103
  fseek(stream_, 0L, SEEK_END);
104
  fsize = ftell(stream_);
105
  if (fsize == 0)
106
  {
107
    /* This is a new file, should write a [ char */
108
    fprintf(stream_, "[\n");
109
  }
110
  else
111
  {
112
    /* We should overwrite the ] character at the end to get a valid
113
       json file at the end
114
    */
115
    fseek(stream_, -1L, SEEK_END);
116
    if (fsize > 5)
117
    {
118
      /* This json is not empty, we should write ',' characters */
119
      ++entryCount;
120
    }
121
  }
122

123
  for (i = 0; i < actions_->size; ++i)
124
  {
125
    writeAction(stream_, wd_, (const LoggerAction*) actions_->data[i], &entryCount);
126
  }
127

128
  fprintf(stream_, "]");
129

130
  /* An fclose also closes the file descriptor, so wo only call an fflush
131
   * here */
132
  fflush(stream_);
133
}
134

135
static int aquireLock(char const* logFile_)
136
{
137
  char lockFilePath[PATH_MAX];
138
  int lockFile;
139

140
  if (!loggerMakePathAbs(logFile_, lockFilePath, 0))
141
  {
142
    return -1;
143
  }
144

145
  strcat(lockFilePath, ".lock");
146
  lockFile = open(lockFilePath, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
147
  if (lockFile == -1)
148
  {
149
    return -1;
150
  }
151

152
  if (flock(lockFile, LOCK_EX) == -1)
153
  {
154
    close(lockFile);
155
    return -1;
156
  }
157

158
  return lockFile;
159
}
160

161
static void freeLock(int lockFile_)
162
{
163
  if (lockFile_ != -1)
164
  {
165
    flock(lockFile_, LOCK_UN);
166
    close(lockFile_);
167
  }
168
}
169

170
static void logProgramArgs(
171
  FILE* stream_,
172
  char const* prog_,
173
  int argc_,
174
  char const* argv_[])
175
{
176
  char const** argList;
177
  LoggerVector actions;
178
  char workingDir[PATH_MAX];
179

180
  if (!loggerMakePathAbs(".", workingDir, 1))
181
  {
182
    return;
183
  }
184

185
  /* Convert argument vector to a NULL terminated list */
186
  argList = (char const **) malloc(sizeof(char*) * (argc_ + 1));
187
  if (argList)
188
  {
189
    memcpy(argList, argv_, sizeof(char*) * argc_);
190
    argList[argc_] = NULL;
191
  }
192
  else
193
  {
194
    return;
195
  }
196

197
  loggerVectorInitAdv(&actions, 10, (LoggerFreeFuc) &loggerActionFree);
198

199
  loggerCollectActionsByProgName(prog_, argList, &actions);
200

201
  writeActions(stream_, workingDir, &actions);
202

203
  loggerVectorClear(&actions);
204
  free(argList);
205
}
206

207
/**
208
 * Logger entry point.
209
 *
210
 * The first argument should be the first argument of the exec* call, the rest
211
 * is the argument vector.
212
 *
213
 * @param argc_ argument counter.
214
 * @param argv_ argument vector (see above).
215
 * @return see a UNIX book.
216
 */
217
int logExec(int argc_, char const* argv_[])
218
{
219
  int lockFd;
220
  int logFd;
221
  FILE* stream;
222
  char const* logFileEnv;
223

224
  if (argc_ < 2)
225
  {
226
    return -1;
227
  }
228

229
  logFileEnv = getenv("CC_LOGGER_FILE");
230
  if (!logFileEnv)
231
  {
232
    return -3;
233
  }
234

235
  lockFd = aquireLock(logFileEnv);
236
  if (lockFd == -1)
237
  {
238
    return -5;
239
  }
240

241
  logFd = open(logFileEnv, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
242
  if (logFd == -1)
243
  {
244
    freeLock(lockFd);
245
    return -7;
246
  }
247

248
  stream = fdopen(logFd, "w+");
249
  if (!stream)
250
  {
251
    close(logFd);
252
    freeLock(lockFd);
253
    return -9;
254
  }
255

256
  logProgramArgs(stream, argv_[0], argc_ - 1, argv_ + 1);
257

258
  fclose(stream); /* fclose also calls close() */
259
  freeLock(lockFd);
260

261
  return 0;
262
}
263

264
#ifdef __LOGGER_MAIN__
265
int main(int argc_, char const* argv_[])
266
{
267
  return logExec(argc_ - 1, argv_ + 1);
268
}
269
#endif
270

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.