changed TOKEN of FFAKEHOST2 to NFH
[srvx.git] / src / proto-p10.c
index 1265aea61562b7036311942ab6c883fd32a5ef93..4db33d8ae38f0d57ea39a45ecd34553bf499b582 100644 (file)
 #define TOK_EOB_ACK             "EA"
 #define TOK_ERROR               "Y"
 #define TOK_FAKEHOST            "FA"
-#define TOK_FAKEHOST2           "FA2"
+#define TOK_FAKEHOST2           "NFH"
 #define TOK_GET                 "GET"
 #define TOK_GLINE               "GL"
 #define TOK_HASH                "HASH"
@@ -702,12 +702,16 @@ irc_introduce(const char *passwd)
 void
 irc_gline(struct server *srv, struct gline *gline)
 {
+    //<prefix> GL <target> [!][+|-|>|<]<mask> [<expiration>] [<lastmod>] [<lifetime>] [:<reason>]
+    //expiration = relative time (seconds)
+    //lastmod = timestamp
+    //livetime = timestamp
     if (gline->lastmod)
-        putsock("%s " P10_GLINE " %s +%s %lu %lu %lu :%s",
-                self->numeric, (srv ? srv->numeric : "*"), gline->target, gline->expires, gline->lastmod, gline->lifetime, gline->reason);
+        putsock("%s " P10_GLINE " %s +%s %lu %lu %lu :%s", self->numeric, (srv ? srv->numeric : "*"), 
+                gline->target, gline->expires-now, gline->lastmod, gline->lifetime, gline->reason);
     else
-        putsock("%s " P10_GLINE " %s +%s %lu :%s",
-                self->numeric, (srv ? srv->numeric : "*"), gline->target, gline->expires, gline->reason);
+        putsock("%s " P10_GLINE " %s +%s %lu :%s", self->numeric, (srv ? srv->numeric : "*"), 
+                gline->target, gline->expires-now, gline->reason);
 }
 
 void
@@ -2557,7 +2561,7 @@ keyncpy(char output[], char input[], size_t output_size)
 }
 
 struct mod_chanmode *
-mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, unsigned int flags, short base_oplevel)
+mod_chanmode_parse(struct chanNode *channel, struct userNode *user, char **modes, unsigned int argc, unsigned int flags, short base_oplevel)
 {
     struct mod_chanmode *change;
     unsigned int ii, in_arg, ch_arg, add;
@@ -2644,10 +2648,11 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
                            if (in_arg >= argc)
                     goto error;
                 char *mode = modes[in_arg++];
-                if(mode[0] == '!' && !(flags & MCP_OPERMODE)) { //noflood flag also for overriders
-                    //only allow opers
-                    goto error;
-                }
+                if(mode[0] == '!' && !(flags & MCP_OPERMODE)) //noflood flag also for overriders
+                   goto error;//only allow opers
+                else if(mode[0] == '!')
+                   mode++;
+                
                 if(mode[0] == '+' || mode[0] == '@') {
                     mode++;
                 }
@@ -2676,8 +2681,28 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
             if (add) {
                 if (in_arg >= argc)
                     goto error;
+                char *altchan = modes[in_arg++];
+                struct chanNode *target;
+                if(!IsChannelName(altchan) || !(target = GetChannel(altchan)))
+                    goto error;
+                if(!(flags & MCP_OPERMODE)) {
+                    //check if the user has the permissions to use this channel as target
+                    struct modeNode *mn;
+                    struct userData *uData;
+                    struct chanData *cData;
+                    if(user && (mn = GetUserMode(target, user)) && (mn->modes & MODE_CHANOP)) {
+                        //allow - user is opped on target channel
+                    } else if(user && user->handle_info && 
+                              (uData = GetChannelUser(channel->channel_info, user->handle_info)) && 
+                              (cData = uData->channel) && 
+                              uData->access >= cData->lvlOpts[lvlGiveOps]
+                             ) {
+                        //allow - user has access to get op on the channel
+                    } else 
+                        goto error;
+                }
                 change->modes_set |= MODE_ALTCHAN;
-                safestrncpy(change->new_altchan, modes[in_arg++], sizeof(change->new_altchan));
+                safestrncpy(change->new_altchan, altchan, sizeof(change->new_altchan));
             } else {
                 change->modes_clear |= MODE_ALTCHAN;
             }