This file is indexed.

/usr/lib/python2.7/dist-packages/gozerbot/fleet.py is in gozerbot 0.99.1-5.

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
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
# gozerbot/fleet.py
#
#

""" fleet is a list of bots. """

__copyright__ = 'this file is in the public domain'

# ==============
# IMPORT SECTION

# gozerbot imports

from gozerbot.datadir import datadir
from utils.exception import handle_exception
from utils.generic import waitforqueue
from utils.log import rlog
from utils.locking import lockdec
from threads.thr import start_new_thread, threaded
from config import Config, fleetbotconfigtxt, config
from users import users
from plugins import plugins
from simplejson import load

# basic imports

import Queue, os, types, threading, time, pickle, glob, logging, shutil, thread

# END IMPORT

# ============
# LOCK SECTION

fleetlock = thread.allocate_lock()
fleetlocked = lockdec(fleetlock)

# END LOCK
# ========

## START

class FleetBotAlreadyExists(Exception):
    pass


class Fleet(object):

    """
        a fleet contains multiple bots (list of bots). used the datadir
        set in gozerbot/datadir.py

    """

    def __init__(self):
        self.datadir = datadir + os.sep + 'fleet'
        if hasattr(os, 'mkdir'):
            if not os.path.exists(self.datadir):
                os.mkdir(self.datadir)
        self.startok = threading.Event()
        self.bots = []

    def getfirstbot(self):

        """
            return the main bot of the fleet.

            :rtype: gozerbot.botbase.BotBase

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.getfirstbot

        """
        self.startok.wait()
        return self.bots[0]

    def getfirstjabber(self):

        """
            return the first jabber bot of the fleet.

            :rtype: gozerbot.botbase.BotBase

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.getfirstjabber

        """

        self.startok.wait()

        for bot in self.bots:
            if bot.type == 'xmpp':
               return bot
        
    def size(self):

        """
             return number of bots in fleet.

             :rtype: integer

             .. literalinclude:: ../../gozerbot/fleet.py
                 :pyobject: Fleet.size

        """

        return len(self.bots)

    def resume(self, sessionfile):

        """
            resume bot from session file.

            :param sessionfile: filename of the session data file
            :type sessionfile: string

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.resume
        """

        # read JSON session file
        session = load(open(sessionfile))

        #  resume bots in session file
        for name in session['bots'].keys():
            reto = None
            if name == session['name']:
                reto = session['channel']
            start_new_thread(self.resumebot, (name, session['bots'][name], reto))

        # allow 5 seconds for bots to resurrect
        time.sleep(5)

        # set start event
        self.startok.set()

    def makebot(self, name, cfg=None):

        """
            create a bot .. use configuration if provided.

            :param name: the name of the bot
            :type name: string
            :param cfg: configuration file for the bot
            :type cfg: gozerbot.config.Config

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.makebot

        """

        if self.byname(name):
            raise FleetBotAlreadyExists("there is already a %s bot in the fleet" % name)

        rlog(10, 'fleet', 'making bot')
        bot = None

        # if not config create a default bot
        if not cfg:
            cfg = Config(self.datadir + os.sep + name, 'config', inittxt=fleetbotconfigtxt)
            cfg.save()

        # create bot based on type 
        if cfg['type'] == 'irc':
            from gozerbot.irc.bot import Bot
            bot = Bot(name, cfg)
        elif cfg['type'] == 'xmpp' or cfg['type'] == 'jabber':
            from gozerbot.xmpp.bot import Bot
            bot = Bot(name, cfg)
        elif cfg['type'] == 'gozernet':
            from gozerbot.gozernet.bot import GozerNetBot
            bot = GozerNetBot(name, cfg)
        else:
            rlog(10, 'fleet', '%s .. unproper type: %s' % (cfg['name'], cfg['type']))

        # set bot name and initialize bot
        if bot:
            cfg['name'] = bot.name = name
            self.initbot(bot)
            return bot

        # failed to created the bot
        raise Exception("can't make %s bot" % name)

    def resumebot(self, botname, data={}, printto=None):

        """
            resume individual bot.

            :param botname: name of the bot to resume
            :type botname: string
            :param data: resume data
            :type data: dict
            :param printto: whom to reply to that resuming is done
            :type printto: nick or JID

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.resumebot

        """

        # see if we need to exit the old bot
        oldbot = self.byname(botname)
        if oldbot:
            oldbot.exit()

        # recreate config file of the bot
        cfg = Config(datadir + os.sep + 'fleet' + os.sep + botname, 'config')

        # make the bot and resume (IRC) or reconnect (Jabber)
        bot = self.makebot(botname, cfg)
        rlog(100, 'fleet', 'bot made: %s' % str(bot))

        if bot:
            if oldbot:
                self.replace(oldbot, bot)
            else:
                self.bots.append(bot)

            if not bot.jabber:
                bot._resume(data, printto)
            else:
                start_new_thread(bot.connectwithjoin, ())

    def start(self, botlist=[], enable=False):

        """
            startup the bots.

            :param botlist: list of bots to start .. if not provided the bots in the gozerdata/fleet dir will be used
            :type botlist: list
            :param enable: whether the bot should be enabled 
            :type enable: boolean

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.start

        """

        # scan the fleet datadir for bots
        dirs = []
        got = []
        for bot in botlist:
            dirs.append(self.datadir + os.sep + bot)

        if not dirs:
            dirs = glob.glob(self.datadir + os.sep + "*")

        for fleetdir in dirs:

            if fleetdir.endswith('fleet'):
                continue

            rlog(10, 'fleet', 'found bot: ' + fleetdir)
            cfg = Config(fleetdir, 'config')

            if not cfg:
                rlog(10, 'fleet', "can't read %s config file" % fleetdir)
                continue

            name = fleetdir.split(os.sep)[-1]

            if not name:
                rlog(10, 'fleet', "can't read botname from %s config file" % \
fleetdir)
                continue

            if not enable and not cfg['enable']:
                rlog(10, 'fleet', '%s bot is disabled' % name)
                continue
            else:
                rlog(10, 'fleet', '%s bot is enabled' % name)

            if not name in fleetdir:
                rlog(10, 'fleet', 'bot name in config file doesnt match dir name')
                continue

            try:
                bot = self.makebot(name, cfg)
            except FleetBotAlreadyExists:
                rlog(10, 'fleet', 'there is already a fleetbot with the name %s' % name)
                continue

            if bot:
                self.addbot(bot)
                start_new_thread(bot.connectwithjoin, ())
                got.append(bot)

        # set startok event
        self.startok.set()

        return got

    def save(self):

        """
            save fleet data and call save on all the bots.

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.save

        """

        for i in self.bots:

            try:
                i.save()
            except Exception, ex:
                handle_exception()

    def avail(self):

        """
            show available fleet bots.

            :rtype: list

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.avail

        """

        return os.listdir(self.datadir)

    def list(self):

        """
            return list of bot names.

            :rtype: list

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.list

        """

        result = []

        for i in self.bots:
            result.append(i.name)

        return result

    def stopall(self):

        """ 
            call stop() on all fleet bots.

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.stopall

        """

        for i in self.bots:

            try:
                i.stop()
            except:
                pass

    def byname(self, name):

        """
            return bot by name.

            :param name: name of the bot
            :type name: string

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.byname

        """

        for i in self.bots:
            if name == i.name:
                return i

    def replace(self, name, bot):

        """
            replace bot with a new bot.

            :param name: name of the bot to replace
            :type name: string
            :param bot: bot to replace old bot with
            :type bot: gozerbot.botbase.BotBase

            .. literalinclude:: ../../gozerbot/fleet.py
                 :pyobject: Fleet.replace

        """

        for i in range(len(self.bots)):
            if name == self.bots[i].name:
                self.bots[i] = bot
                return

    def initbot(self, bot):

        """
            initialise a bot.

            :param bot: bot to initialise
            :type bot: gozerbot.botbase.BotBase

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.initbot

        """

        if bot not in self.bots:

            if not os.path.exists(self.datadir + os.sep + bot.name):
                os.mkdir(self.datadir + os.sep + bot.name)

            if type(bot.cfg['owner']) == types.StringType or type(bot.cfg['owner']) == types.UnicodeType:
                bot.cfg['owner'] = [bot.cfg['owner'], ]
                bot.cfg.save()

            users.make_owner(config['owner'] + bot.cfg['owner'])
            rlog(10, 'fleet', 'added bot: ' + bot.name)

    @fleetlocked
    def addbot(self, bot):

        """
            add a bot to the fleet .. remove all existing bots with the 
            same name.

            :param bot: bot to add
            :type bot: gozerbot.botbase.BotBase
            :rtype: boolean

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.addbot
            
        """

        if bot:

            for i in range(len(self.bots)-1, -1, -1):
                if self.bots[i].name == bot.name:
                    rlog(10, 'fleet', 'removing %s from fleet' % bot.name)
                    del self.bots[i]

            rlog(10, 'fleet', 'adding %s' % bot.name)
            self.bots.append(bot)
            return True

        return False

    def connect(self, name):

        """
            connect bot to the server.

            :param name: name of the bot
            :type name: string
            :rtype: boolean

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.connect

        """

        for i in self.bots:

            if i.name == name:
                got = i.connect()

                if got:
                    start_new_thread(i.joinchannels, ())
                    return True
                else:
                    return False

    @fleetlocked
    def delete(self, name):

        """
            delete bot with name from fleet.

            :param name: name of bot to delete
            :type name: string
            :rtype: boolean

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.delete

        """

        for i in self.bots:

            if i.name == name:
                i.exit()
                self.remove(i)
                i.cfg['enable'] = 0
                i.cfg.save()
                rlog(10, 'fleet', '%s disabled' % i.name)
                return True

        return False


    def remove(self, bot):

        """
            delete bot by object.

            :param bot: bot to delete
            :type bot: gozerbot.botbase.BotBase
            :rtype: boolean

            .. literalinclude:: ../../gozerbot/fleet.py
                 :pyobject: Fleet.remove

        """

        try:
            self.bots.remove(bot)
            return True
        except ValueError:
            return False

    def exit(self, name=None, jabber=False):

        """
            call exit on all bots. if jabber=True only jabberbots will exit.

            :param name: name of the bot to exit. if not provided all bots will exit.
            :type name: string
            :param jabber: flag to set when only jabberbots should exit
            :type jabber: boolean
            :rtype: boolean

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.exit

        """
        
        if not name:
            threads = []

            for i in self.bots:
                if jabber and not i.jabber:
                    pass
                else:
                    threads.append(start_new_thread(i.exit, ()))

            for thr in threads:
                thr.join()

            return


        for i in self.bots:

            if i.name == name:
                try:
                    i.exit()
                except:
                    handle_exception()
                self.remove(i)
                return True

        return False

    def cmnd(self, event, name, cmnd):
 
        """
            do command on a bot.

            :param event: event to pass on to the dispatcher
            :type event: gozerbot.event.EventBase
            :param name: name of the bot to pass on to the dispatcher
            :type name: string
            :param cmnd: command to execute on the fleet bot
            :type cmnd: string

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.cmnd

        """

        bot = self.byname(name)

        if not bot:
            return 0

        from gozerbot.eventbase import EventBase
        j = plugins.clonedevent(bot, event)
        j.onlyqueues = True
        j.txt = cmnd
        q = Queue.Queue()
        j.queues = [q]
        j.speed = 3
        start_new_thread(plugins.trydispatch, (bot, j))
        result = waitforqueue(q)

        if not result:
            return

        res = ["<%s>" % bot.name, ]
        res += result
        event.reply(res)

    def cmndall(self, event, cmnd):

        """
            do a command on all bots.

            :param event: event to pass on to dispatcher
            :type event: gozerbot.eventbase.EventBase
            :param cmnd: the command string to execute
            :type cmnd: string

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.cmndall

        """

        threads = []

        for i in self.bots:
            thread = start_new_thread(self.cmnd, (event, i.name, cmnd))
            threads.append(thread)

        for i in threads:
            i.join()

    def broadcast(self, txt):

        """
            broadcast txt to all bots.

            :param txt: text to broadcast on all bots
            :type txt: string

            .. literalinclude:: ../../gozerbot/fleet.py
                :pyobject: Fleet.broadcast

        """

        for i in self.bots:
            i.broadcast(txt)

# ============
# INIT SECTION


# main fleet object
fleet = Fleet()

# END INIT
# ========