Fossil SCM

fossil-scm / src / fshell.c
Blame History Raw 131 lines
1
/*
2
** Copyright (c) 2016 D. Richard Hipp
3
**
4
** This program is free software; you can redistribute it and/or
5
** modify it under the terms of the Simplified BSD License (also
6
** known as the "2-Clause License" or "FreeBSD License".)
7
8
** This program is distributed in the hope that it will be useful,
9
** but without any warranty; without even the implied warranty of
10
** merchantability or fitness for a particular purpose.
11
**
12
** Author contact information:
13
** [email protected]
14
** http://www.hwaci.com/drh/
15
**
16
*******************************************************************************
17
**
18
** This module contains the code that implements the "fossil shell" command.
19
**
20
** The fossil shell prompts for lines of user input, then parses each line
21
** after the fashion of a standard Bourne shell and forks a child process
22
** to run the corresponding Fossil command. This only works on Unix.
23
**
24
** The "fossil shell" command is intended for use with SEE-enabled fossil.
25
** It allows multiple commands to be issued without having to reenter the
26
** crypto passphrase for each command.
27
*/
28
#include "config.h"
29
#include "fshell.h"
30
#include <ctype.h>
31
32
#ifndef _WIN32
33
# include "linenoise.h"
34
# include <sys/types.h>
35
# include <sys/wait.h>
36
#endif
37
38
39
/*
40
** COMMAND: shell*
41
**
42
** Usage: %fossil shell
43
**
44
** Prompt for lines of input from stdin. Parse each line and evaluate
45
** it as a separate fossil command, in a child process. The initial
46
** "fossil" is omitted from each line.
47
**
48
** This command only works on unix-like platforms that support fork().
49
** It is non-functional on Windows.
50
*/
51
void shell_cmd(void){
52
#ifdef _WIN32
53
fossil_fatal("the 'shell' command is not supported on windows");
54
#else
55
int nArg;
56
int mxArg = 0;
57
int n, i;
58
char **azArg = 0;
59
int fDebug;
60
pid_t childPid;
61
char *zLine = 0;
62
char *zPrompt = 0;
63
fDebug = find_option("debug", 0, 0)!=0;
64
db_find_and_open_repository(OPEN_ANY_SCHEMA|OPEN_OK_NOT_FOUND, 0);
65
if(g.zRepositoryName!=0){
66
zPrompt = mprintf("fossil (%z)> ", db_get("project-name","unnamed"));
67
}else{
68
zPrompt = mprintf("fossil (no repo)> ");
69
}
70
db_close(0);
71
sqlite3_shutdown();
72
linenoiseSetMultiLine(1);
73
while( (free(zLine), zLine = linenoise(zPrompt)) ){
74
/* Remember shell history within the current session */
75
linenoiseHistoryAdd(zLine);
76
77
/* Parse the line of input */
78
n = (int)strlen(zLine);
79
for(i=0, nArg=1; i<n; i++){
80
while( fossil_isspace(zLine[i]) ){ i++; }
81
if( i>=n ) break;
82
if( nArg>=mxArg ){
83
mxArg = nArg+10;
84
azArg = fossil_realloc(azArg, sizeof(char*)*mxArg);
85
if( nArg==1 ) azArg[0] = g.argv[0];
86
}
87
if( zLine[i]=='"' || zLine[i]=='\'' ){
88
char cQuote = zLine[i];
89
i++;
90
azArg[nArg++] = &zLine[i];
91
for(i++; i<n && zLine[i]!=cQuote; i++){}
92
}else{
93
azArg[nArg++] = &zLine[i];
94
while( i<n && !fossil_isspace(zLine[i]) ){ i++; }
95
}
96
zLine[i] = 0;
97
}
98
99
/* If the --debug flag was used, display the parsed arguments */
100
if( fDebug ){
101
for(i=1; i<nArg; i++){
102
fossil_print("argv[%d] = [%s]\n", i, azArg[i]);
103
}
104
}
105
106
/* Special cases */
107
if( nArg<2 ) continue;
108
if( fossil_strcmp(azArg[1],"exit")==0 ) break;
109
110
/* Fork a process to handle the command */
111
childPid = fork();
112
if( childPid<0 ){
113
printf("could not fork a child process to handle the command\n");
114
fflush(stdout);
115
continue;
116
}
117
if( childPid==0 ){
118
/* This is the child process */
119
int main(int, char**);
120
fossil_main(nArg, azArg);
121
exit(0);
122
}else{
123
/* The parent process */
124
int status;
125
waitpid(childPid, &status, 0);
126
}
127
}
128
free(zPrompt);
129
#endif
130
}
131

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button