This file is indexed.

/usr/share/pyshared/crm/main.py is in pacemaker 1.1.6-2ubuntu3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# Copyright (C) 2008 Dejan Muhamedagic <dmuhamedagic@suse.de>
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
# 
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# 
# You should have received a copy of the GNU General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#

import sys
import shlex
import getopt

from utils import *
from userprefs import Options, UserPrefs
from vars import Vars
from ui import cmd_exit
from msg import *
from levels import Levels

def load_rc(rcfile):
    try: f = open(rcfile)
    except: return
    save_stdin = sys.stdin
    sys.stdin = f
    while True:
        inp = multi_input()
        if inp == None:
            break
        try: parse_line(levels,shlex.split(inp))
        except ValueError, msg:
            common_err(msg)
    f.close()
    sys.stdin = save_stdin

def multi_input(prompt = ''):
    """
    Get input from user
    Allow multiple lines using a continuation character
    """
    line = []
    while True:
        try:
            text = raw_input(prompt)
        except EOFError:
            return None
        err_buf.incr_lineno()
        if options.regression_tests:
            print ".INP:",text
            sys.stdout.flush()
            sys.stderr.flush()
        stripped = text.strip()
        if stripped.endswith('\\'):
            stripped = stripped.rstrip('\\')
            line.append(stripped)
            if prompt:
                prompt = '> '
        else:
            line.append(stripped)
            break
    return ''.join(line)

def check_args(args,argsdim):
    if not argsdim: return True
    if len(argsdim) == 1:
        minargs = argsdim[0]
        return len(args) >= minargs
    else:
        minargs,maxargs = argsdim
        return len(args) >= minargs and len(args) <= maxargs

#
# Note on parsing
#
# Parsing tables are python dictionaries.
#
# Keywords are used as keys and the corresponding values are
# lists (actually tuples, since they should be read-only) or
# classes. In the former case, the keyword is a terminal and
# in the latter, a new object for the class is created. The class
# must have the cmd_table variable.
#
# The list has the following content:
#
# function: a function to handle this command
# numargs_list: number of minimum/maximum arguments; for example,
#   (0,1) means one optional argument, (1,1) one required; if the
#   list is empty then the function will parse arguments itself
# required minimum skill level: operator, administrator, expert
#   (encoded as a small integer from 0 to 2)
# can the command cause transition to start (0 or 1)
#   used to check whether to wait4dc to end the transition
# 

def show_usage(cmd):
    p = None
    try: p = cmd.__doc__
    except: pass
    if p:
        print >> sys.stderr, p
    else:
        syntax_err(cmd.__name__)

def parse_line(lvl,s):
    if not s: return True
    if s[0].startswith('#'): return True
    lvl.mark()
    pt = lvl.parse_root
    cmd = None
    i = 0
    for i in range(len(s)):
        token = s[i]
        if token in pt:
            if type(pt[token]) == type(object):
                # on entering new level we need to set the
                # interactive option _before_ creating the level
                if not options.interactive and i == len(s)-1:
                    set_interactive()
                lvl.new_level(pt[token],token)
                pt = lvl.parse_root # move to the next level
            else:
                cmd = pt[token] # terminal symbol
                break  # and stop parsing
        else:
            syntax_err(s[i:])
            lvl.release()
            return False
    if cmd: # found a terminal symbol
        if not user_prefs.check_skill_level(cmd[2]):
            lvl.release()
            skill_err(s[i])
            return False
        args = s[i+1:]
        if not check_args(args,cmd[1]):
            lvl.release()
            show_usage(cmd[0])
            return False
        args = s[i:]
        d = lambda: cmd[0](*args)
        rv = d() # execute the command
        # should we wait till the command takes effect?
        if user_prefs.get_wait() and rv != False and cmd[3] == 1:
            if not wait4dc(token, not options.batch):
                rv = False
        lvl.release()
        return rv != False
    return True

def prereqs():
    proglist = "which cibadmin crm_resource crm_attribute crm_mon"
    for prog in proglist.split():
        if not is_program(prog):
            print >> sys.stderr, "%s not available, check your installation"%prog
            sys.exit(1)

# three modes: interactive (no args supplied), batch (input from
# a file), half-interactive (args supplied, but not batch)
def cib_prompt():
    return vars.cib_in_use or "live"

def usage(rc):
    f = sys.stderr
    if rc == 0:
        f = sys.stdout
    print >> f, """
usage:
    crm [-D display_type] [-f file] [-hF] [args]

    Use crm without arguments for an interactive session.
    Supply one or more arguments for a "single-shot" use.
    Specify with -f a file which contains a script. Use '-' for
    standard input or use pipe/redirection.

    crm displays cli format configurations using a color scheme
    and/or in uppercase. Pick one of "color" or "uppercase", or
    use "-D color,uppercase" if you want colorful uppercase.
    Get plain output by "-D plain". The default may be set in
    user preferences (options).

    -F stands for force, if set all operations will behave as if
    force was specified on the line (e.g. configure commit).

Examples:

    # crm -f stopapp2.cli
    # crm < stopapp2.cli
    # crm resource stop global_www
    # crm status 

    """
    sys.exit(rc)

user_prefs = UserPrefs.getInstance()
options = Options.getInstance()
err_buf = ErrorBuffer.getInstance()
vars = Vars.getInstance()
levels = Levels.getInstance()

# prefer the user set PATH
os.putenv("PATH", "%s:%s" % (os.getenv("PATH"),vars.crm_daemon_dir))

def set_interactive():
    '''Set the interactive option only if we're on a tty.'''
    if sys.stdin.isatty():
        options.interactive = True

def run():
    prereqs()
    inp_file = ''

    load_rc(vars.rc_file)

    if not sys.stdin.isatty():
        err_buf.reset_lineno()
        options.batch = True
    else:
        options.interactive = True

    try:
        opts, args = getopt.getopt(sys.argv[1:], \
            'whdf:FRD:', ("wait","version","help","debug","file=",\
            "force","regression-tests","display="))
        for o,p in opts:
            if o in ("-h","--help"):
                usage(0)
            elif o in ("--version"):
                print >> sys.stdout,("""%s
Written by Dejan Muhamedagic
""" % vars.crm_version)
                sys.exit(0)

            elif o == "-d":
                user_prefs.set_debug()
            elif o == "-R":
                options.regression_tests = True
            elif o in ("-D","--display"):
                user_prefs.set_output(p)
            elif o in ("-F","--force"):
                user_prefs.set_force()
            elif o in ("-f","--file"):
                options.batch = True
                options.interactive = False
                err_buf.reset_lineno()
                inp_file = p
            elif o in ("-w","--wait"):
                user_prefs.wait = "yes"
    except getopt.GetoptError,msg:
        print msg
        usage(1)

    # this special case is silly, but we have to keep it to
    # preserve the backward compatibility
    if len(args) == 1 and args[0].startswith("conf"):
        parse_line(levels,["configure"])
    elif len(args) > 0:
        err_buf.reset_lineno()
        # we're not sure yet whether it's an interactive session or not
        # (single-shot commands aren't)
        options.interactive = False
        if parse_line(levels,shlex.split(' '.join(args))):
            # if the user entered a level, then just continue
            if not levels.previous():
                sys.exit(0)
        else:
            sys.exit(1)

    if inp_file == "-":
        pass
    elif inp_file:
        try:
            f = open(inp_file)
        except IOError, msg:
            common_err(msg)
            usage(2)
        sys.stdin = f

    if options.interactive and not options.batch:
        from completion import setup_readline
        setup_readline()

    rc = 0
    while True:
        if options.interactive and not options.batch:
            vars.prompt = "crm(%s)%s# " % (cib_prompt(),levels.getprompt())
        inp = multi_input(vars.prompt)
        if inp == None:
            if options.interactive:
                cmd_exit("eof")
            else:
                cmd_exit("eof", rc)
        try:
            if not parse_line(levels,shlex.split(inp)):
                rc = 1
        except ValueError, msg:
            rc = 1
            common_err(msg)

# vim:ts=4:sw=4:et: