
/*
** replcom.sql            1997/02/12 22:03
**
**
** Copyright Microsoft, Inc. 1998-1999
** All Rights Reserved.
** Use, duplication, or disclosure by the United States Government
** is subject to restrictions as set forth in subdivision (c) (1) (ii)
** of the Rights in Technical Data and Computer Software clause
** at CFR 252.227-7013. Microsoft, Inc. One Microsoft Way, Redmond WA
** 98052.  SQL SERVER 7.0.
*/

dump tran master with no_log
go

exec dbo.sp_configure 'update',1
go
reconfigure with override
go

set ANSI_NULLS off
go

use master
go

exec dbo.sp_MS_upd_sysobj_category 1 --Capture time for use at the end
go


dump tran master with no_log
GO

/* 
** Drop the stored procedures in this script using the old dropping SP 
** and then drop itself
*/
if exists (select * from sysobjects
    where type = 'P'
            and name = 'sp_MSdrop_replcom')
begin
    exec dbo.sp_MSdrop_replcom
    drop procedure sp_MSdrop_replcom
end

dump tran msdb with no_log
GO

/*
** Create stored procedures to drop the stored procedures
** created by this script
*/

raiserror('Creating procedure sp_MSdrop_replcom', 0,1)
GO

create procedure sp_MSdrop_replcom
as
    if exists (select * from sysobjects 
        where type = 'P'
            and name = 'sp_MScreate_distributor_tables')
        drop procedure sp_MScreate_distributor_tables

    if exists (select * from sysobjects
        where type = 'P'
                and name = 'sp_MSIfExistsRemoteLogin')
        drop procedure sp_MSIfExistsRemoteLogin

    if exists (select * from sysobjects
        where type = 'P'
                and name = 'sp_helppublicationsync')
        drop procedure sp_helppublicationsync

    if exists (select * from sysobjects
        where type = 'P'
                and name = 'sp_replicationdboption')
        drop procedure sp_replicationdboption

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_addpublication_snapshot')
        drop procedure sp_addpublication_snapshot

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_MShelpobjectpublications')
        drop procedure sp_MShelpobjectpublications

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_addpublisher')
        drop procedure sp_addpublisher

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_addsubscriber')
        drop procedure sp_addsubscriber

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_addsubscriber_schedule')
        drop procedure sp_addsubscriber_schedule

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_changesubscriber_schedule')
        drop procedure sp_changesubscriber_schedule

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_changesubscriber')
        drop procedure sp_changesubscriber

    IF EXISTS (SELECT * FROM sysobjects
            WHERE type = 'P'
                AND name = 'sp_MScreate_dist_tables')
        DROP PROCEDURE sp_MScreate_dist_tables

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_distcounters')
        drop procedure sp_distcounters


    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_droppublisher')
        drop procedure sp_droppublisher

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_dropsubscriber')
        drop procedure sp_dropsubscriber

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_dsninfo')
        drop procedure sp_dsninfo

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_enumdsn')
        drop procedure sp_enumdsn

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_helpdistributor')
        drop procedure sp_helpdistributor

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_helppublicationsync')    /* Remove old version */
        drop procedure sp_helppublicationsync

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_helpreplicationdb')
        drop procedure sp_helpreplicationdb

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_helpsubscriberinfo')
        drop procedure sp_helpsubscriberinfo

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_publishdb')
        drop procedure sp_publishdb

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_replica')
        drop procedure sp_replica

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_adddistributiondb')
        drop procedure sp_adddistributiondb

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_MSexists_file')
        drop procedure sp_MSexists_file

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_changedistributiondb')
        drop procedure sp_changedistributiondb

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_helpdistributiondb')
        drop procedure sp_helpdistributiondb

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_dropdistributiondb')
        drop procedure sp_dropdistributiondb

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_adddistpublisher')
        drop procedure sp_adddistpublisher

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_changedistpublisher')
        drop procedure sp_changedistpublisher

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_helpdistpublisher')
        drop procedure sp_helpdistpublisher

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_dropdistpublisher')
        drop procedure sp_dropdistpublisher

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_MSadd_distributor_alerts_and_responses')
        drop procedure  sp_MSadd_distributor_alerts_and_responses

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_MSdrop_distributor_alerts_and_responses')
        drop procedure  sp_MSdrop_distributor_alerts_and_responses

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_adddistributor')
        drop procedure  sp_adddistributor

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_dropdistributor')
        drop procedure sp_dropdistributor

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_changedistributor_property')
        drop procedure sp_changedistributor_property

    if exists (select * from sysobjects
            where type = 'P'
                and name = 'sp_helpdistributor_properties')
        drop procedure sp_helpdistributor_properties

    if exists (select * from sysobjects
            where type = 'X'
                and name = 'sp_repldone')
        exec dbo.sp_dropextendedproc 'sp_repldone'

    if exists (select * from sysobjects
            where type = 'X'
                and name = 'sp_repltrans')
        exec dbo.sp_dropextendedproc 'sp_repltrans'

    if exists (select * from sysobjects
            where type = 'X'
                and name = 'sp_replcmds')
        exec dbo.sp_dropextendedproc 'sp_replcmds'

    if exists (select * from sysobjects
            where type = 'X'
                and name = 'sp_replcounters')
        exec dbo.sp_dropextendedproc 'sp_replcounters'

    if exists (select * from sysobjects
            where type = 'X'
                and name = 'sp_replflush')
        exec dbo.sp_dropextendedproc 'sp_replflush'

    if exists (select * from sysobjects
            where type = 'X'
                 and name = 'sp_replpostcmd' )
        exec dbo.sp_dropextendedproc 'sp_replpostcmd'

    if exists (select * from sysobjects
            where type = 'X'
                 and name = 'sp_replincrementlsn' )
        exec dbo.sp_dropextendedproc 'sp_replincrementlsn'

    if exists (select * from sysobjects
            where type = 'X'
                 and name = 'sp_replupdateschema' )
        exec dbo.sp_dropextendedproc 'sp_replupdateschema'

    if exists (select * from sysobjects
            where type = 'X'
                 and name = 'sp_replsetoriginator' )
        exec dbo.sp_dropextendedproc 'sp_replsetoriginator'

    if exists (select * from sysobjects
            where type = 'X'
                and name = 'xp_enumdsn')
        exec dbo.sp_dropextendedproc 'xp_enumdsn'

    if exists (select * from sysobjects
            where type = 'X'
                and name = 'xp_oledbinfo')
        exec dbo.sp_dropextendedproc 'xp_oledbinfo'

    if exists (select * from sysobjects
            where type = 'X'
                and name = 'xp_dsninfo')
        exec dbo.sp_dropextendedproc 'xp_dsninfo'

    if exists (select * from sysobjects
            where type = 'X'
                and name = 'xp_repl_encrypt')
        exec dbo.sp_dropextendedproc 'xp_repl_encrypt'

    -- sp_helpsubscriber is removed permanently from the system.
    if exists (select * from sysobjects
        where type = 'P'
                and name = 'sp_helpsubscriber')
        drop procedure sp_helpsubscriber

	-- sp_MSrepl_encrypt obsolete; use xp_repl_encrypt
    if exists (select * from sysobjects
        where type = 'P'
                and name = 'sp_MSrepl_encrypt')
        drop procedure sp_MSrepl_encrypt

    if exists (select * from sysobjects 
        where name = 'sp_add_agent_profile' 
                and type = 'P')
        drop procedure sp_add_agent_profile

    if exists (select * from sysobjects 
        where name = 'sp_help_agent_profile' 
                and type = 'P')
        drop procedure sp_help_agent_profile

    if exists (select * from sysobjects 
        where name = 'sp_help_agent_default' 
            and type = 'P')
        drop procedure sp_help_agent_default

    if exists (select * from sysobjects 
        where name = 'sp_drop_agent_profile' 
                and type = 'P')
        drop procedure sp_drop_agent_profile

    if exists (select name from sysobjects 
        where name = 'sp_MSupdate_agenttype_default'
                and type = 'P')
        drop procedure sp_MSupdate_agenttype_default

    if exists (select * from sysobjects 
        where name = 'sp_MSvalidate_agent_parameter' 
                and type = 'P')
        drop procedure sp_MSvalidate_agent_parameter

    if exists (select * from sysobjects 
        where name = 'sp_add_agent_parameter' 
                and type = 'P')
        drop procedure sp_add_agent_parameter

    if exists (select * from sysobjects 
        where name = 'sp_generate_agent_parameter' 
                and type = 'P')
        drop procedure sp_generate_agent_parameter

    if exists (select * from sysobjects 
        where name = 'sp_change_agent_parameter' 
                and type = 'P')
        drop procedure sp_change_agent_parameter

    if exists (select * from sysobjects 
        where name = 'sp_change_agent_profile' 
                and type = 'P')
        drop procedure sp_change_agent_profile

    if exists (select * from sysobjects 
        where name = 'sp_help_agent_parameter' 
                and type = 'P')
      drop procedure sp_help_agent_parameter

    if exists (select * from sysobjects 
        where name = 'sp_drop_agent_parameter' 
                and type = 'P')
      drop procedure sp_drop_agent_parameter

    if exists (select * from sysobjects 
        where name = 'sp_MShelp_distdb' 
                and type = 'P')
      drop procedure sp_MShelp_distdb

    if exists (select * from sysobjects 
        where name = 'sp_MShelp_distdb' 
                and type = 'P')
      drop procedure sp_MShelp_distdb

    if exists (select * from sysobjects 
        where name = 'sp_MSenum_misc_agents'
                and type = 'P')
      drop procedure sp_MSenum_misc_agents

    if exists (select * from sysobjects 
        where name = 'sp_MSupdate_replication_status' 
                and type = 'P')
      drop procedure sp_MSupdate_replication_status

    if exists (select * from sysobjects 
        where name = 'sp_MSload_replication_status' 
                and type = 'P')
      drop procedure sp_MSload_replication_status

    if exists (select * from sysobjects 
        where name = 'sp_MScreate_replication_status_table' 
                and type = 'P')
      drop procedure sp_MScreate_replication_status_table

    if exists (select * from sysobjects 
        where name = 'sp_MShelp_replication_status' 
                and type = 'P')
      drop procedure sp_MShelp_replication_status

    if exists (select * from sysobjects 
        where name = 'sp_MSenum_replication_agents' 
                and type = 'P')
      drop procedure sp_MSenum_replication_agents

    if exists (select * from sysobjects 
        where name = 'sp_replication_agent_checkup' 
                and type = 'P')
      drop procedure sp_replication_agent_checkup

    if exists (select * from sysobjects 
        where name = 'sp_MSreplrole' 
                and type = 'P')
      drop procedure sp_MSreplrole

    if exists (select * from sysobjects 
        where name = 'sp_MScreate_replication_checkup_agent' 
                and type = 'P')
      drop procedure sp_MScreate_replication_checkup_agent

    if exists (select * from sysobjects 
        where name = 'sp_MSenum_replication_job' 
                and type = 'P')
      drop procedure sp_MSenum_replication_job

    if exists (select * from sysobjects 
        where name = 'sp_MSrepl_dbrole' 
                and type = 'P')
      drop procedure sp_MSrepl_dbrole

    if exists (select * from sysobjects
        where type = 'P'
                and name = 'sp_oledbinfo')
        drop procedure sp_oledbinfo

    if exists (select * from sysobjects
        where type = 'P'
                and name = 'sp_enumoledbdatasources')
        drop procedure sp_enumoledbdatasources

    if exists (select * from sysobjects
        where type = 'P'
                and name = 'sp_MSget_oledbinfo')
        drop procedure sp_MSget_oledbinfo

    if exists (select * from sysobjects 
        where name = 'sp_changedistributor_password' 
                and type = 'P')
      drop procedure sp_changedistributor_password

    if exists (select * from sysobjects 
        where name = 'sp_grant_publication_access' 
                and type = 'P')
      drop procedure sp_grant_publication_access

    if exists (select * from sysobjects 
        where name = 'sp_revoke_publication_access' 
                and type = 'P')
      drop procedure sp_revoke_publication_access

    if exists (select * from sysobjects 
        where name = 'sp_help_publication_access' 
                and type = 'P')
      drop procedure sp_help_publication_access

    if exists (select * from sysobjects 
        where name = 'sp_check_publication_access' 
                and type = 'P')
      drop procedure sp_check_publication_access

    if exists (select * from sysobjects 
        where name = 'sp_MSinit_replication_perfmon' 
                and type = 'P')
      drop procedure sp_MSinit_replication_perfmon

    if exists (select * from sysobjects 
        where name = 'sp_MSrepl_startup' 
                and type = 'P')
      drop procedure sp_MSrepl_startup

    if exists (select * from sysobjects 
        where name = 'sp_MSflush_access_cache' 
                and type = 'P')
      drop procedure sp_MSflush_access_cache

    if exists (select * from sysobjects 
        where name = 'sp_MSreinit_failed_subscriptions' 
                and type = 'P')
      drop procedure sp_MSreinit_failed_subscriptions

    if exists (select * from sysobjects 
        where name = 'sp_add_datatype_mapping' 
                and type = 'P')
        drop procedure sp_add_datatype_mapping
    
    if exists (select * from sysobjects 
        where name = 'sp_help_datatype_mapping' 
                and type = 'P')
        drop procedure sp_help_datatype_mapping

    if exists (select * from sysobjects 
        where name = 'sp_MSfix_6x_tasks' 
                and type = 'P')
        drop procedure sp_MSfix_6x_tasks
GO

/* 
**  We must execute dbo.sp_MSdrop_replcom here since sp_MSdrop_replcom may not exist
**  before this script is applied and it is possible
**  that some replication sps are left. (We ignore error when dropping
**  the replication so it is possible sp_MSdrop_replcom is dropped but
**  some replication sps were left).
*/
exec dbo.sp_MSdrop_replcom
go

dump tran msdb with no_log
GO

raiserror('Creating procedure sp_MScreate_distributor_tables', 0,1)
GO

create procedure sp_MScreate_distributor_tables
as
    declare @profile_id     int
    declare @retcode    int
    declare @profile_name nvarchar(100)
    declare @profile_desc nvarchar(100)

    /* Create MSpublishers table */
    IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSdistpublishers'
        and xtype = 'U')
    begin
        DROP TABLE msdb..MSdistpublishers
        if @@error<> 0 goto FAILURE
    end

    /* Create MSdistributiondbs table */
    IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSdistributiondbs'
        and xtype = 'U')
    begin
        DROP TABLE msdb..MSdistributiondbs
        if @@error<> 0 goto FAILURE
    end

    /* create MSdistributor table */
    IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSdistributor'
        and xtype = 'U')
    begin
        DROP TABLE msdb..MSdistributor
        if @@error<> 0 goto FAILURE
    end

    /* create sysreplicationalerts table */
    IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'sysreplicationalerts'
        and xtype = 'U')
    begin
        DROP TABLE msdb..sysreplicationalerts
        if @@error<> 0 goto FAILURE
    end
    
    /* create MSagent_profiles table */
    IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSagent_profiles'
        and xtype = 'U')
    begin
        DROP TABLE msdb..MSagent_profiles
        if @@error<> 0 goto FAILURE
    end

    /* create MSagent_parameters table */
    IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSagent_parameters' 
        and xtype = 'U')
    begin
        DROP TABLE msdb..MSagent_parameters
        if @@error<> 0 goto FAILURE
    end

    /* create MSdatatype_mappings table */
    IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSdatatype_mappings' 
        and xtype = 'U')
    begin
        DROP TABLE msdb..MSdatatype_mappings
        if @@error<> 0 goto FAILURE
    end

    
    CREATE TABLE msdb.dbo.MSdistpublishers
    (
        name                sysname     NOT NULL,
        distribution_db     sysname     NOT NULL,
        working_directory   nvarchar(255) NOT NULL,
        security_mode       int         NOT NULL,
        login               sysname     NOT NULL,
        password            sysname     NULL,
        active              bit         NOT NULL,
        trusted             bit         NOT NULL,
        thirdparty_flag     bit         NOT NULL
    )
    if @@error<> 0 goto FAILURE


    CREATE TABLE msdb.dbo.MSdistributiondbs
    (
        name            sysname     NOT NULL,
        min_distretention   int     NOT NULL,
        max_distretention   int     NOT NULL,
        history_retention   int     NOT NULL
    )
    if @@error<> 0 goto FAILURE

    CREATE TABLE msdb.dbo.MSdistributor 
    ( 
        property        sysname     NOT NULL, 
        value           nvarchar(3000)  NULL
    )
    if @@error<> 0 goto FAILURE

    CREATE TABLE msdb.dbo.sysreplicationalerts
    (
        alert_id            int identity(1,1) NOT NULL,
        status              int NOT NULL,
        agent_type          int NULL,
        agent_id            int NULL,
        error_id            int NULL,
        alert_error_code    int NULL,
        time                datetime NOT NULL,
        publisher           sysname NULL,
        publisher_db        sysname NULL,
        publication         sysname NULL,
        publication_type    int NULL,
        subscriber          sysname NULL,
        subscriber_db       sysname NULL,
        article             sysname NULL,
        destination_object  sysname NULL,
        source_object       sysname NULL,
        alert_error_text    ntext NULL
    )
    if @@error<> 0 goto FAILURE

    CREATE UNIQUE CLUSTERED INDEX ucsysreplicationalerts ON msdb.dbo.sysreplicationalerts(alert_id)
    if @@error<> 0 goto FAILURE

    CREATE TABLE msdb.dbo.MSagent_profiles
    (
        profile_id    int           NOT NULL IDENTITY,
        profile_name  sysname       NOT NULL,
        agent_type          int             NOT NULL, -- 1-Snapshot, 2-Logreader,
                                                      -- 3-Distribution, 4-Merge
        type                int             NOT NULL, -- 0-System, 1-Custom
        description         nvarchar(3000)  NULL,
        def_profile   bit               NOT NULL
    )
    if @@error<> 0 goto FAILURE


    CREATE UNIQUE CLUSTERED INDEX ucMSagent_profiles ON msdb.dbo.MSagent_profiles
        (profile_name, profile_id, agent_type)
    if @@error<> 0 goto FAILURE

    CREATE TABLE msdb.dbo.MSagent_parameters
    (
        profile_id     int          NOT NULL,
        parameter_name       sysname        NOT NULL,
        value                nvarchar(255)  NOT NULL
    )
    if @@error<> 0 goto FAILURE

    CREATE UNIQUE CLUSTERED INDEX ucMSagent_parameters ON msdb.dbo.MSagent_parameters
        (parameter_name, profile_id)
    if @@error<> 0 goto FAILURE

    /* 
	** Create default / non default profiles 
	** for all the agents 
	*/

    /* 
	** Snapshot agent 
	*/
    set @profile_id = NULL
    set @profile_name = formatmessage(20545) -- Default Snapshot Profile
    set @profile_desc = NULL

    exec @retcode = dbo.sp_add_agent_profile
            @profile_id = @profile_id OUT,
            @profile_name = @profile_name,
            @agent_type = 1,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
            @profile_type = 0,   -- 0-System, 1-Custom 
            @description = @profile_desc,
            @default = 1
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

	exec @retcode = dbo.sp_generate_agent_parameter @profile_id
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    /* 
	** Logreader agent 
	*/
    set @profile_id = NULL
    set @profile_name = formatmessage(20545) -- Default LogReader Profile
    set @profile_desc = NULL

    exec @retcode = dbo.sp_add_agent_profile
            @profile_id = @profile_id OUT,
            @profile_name = @profile_name,
            @agent_type = 2,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
            @profile_type = 0,   -- 0-System, 1-Custom 
            @description = @profile_desc,
            @default = 1
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    exec @retcode = dbo.sp_generate_agent_parameter @profile_id
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    /* 
	** Logreader agent - Verbose History Profile
	*/
    set @profile_id = NULL
    set @profile_name = formatmessage(20546) -- LogReader Verbose History Profile
    set @profile_desc = formatmessage(20547)

    exec @retcode = dbo.sp_add_agent_profile
            @profile_id = @profile_id OUT,
            @profile_name = @profile_name,
            @agent_type = 2,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
            @profile_type = 0,   -- 0-System, 1-Custom 
            @description = @profile_desc,
            @default = 0
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    exec @retcode = dbo.sp_generate_agent_parameter @profile_id
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    /* 
	** Distribution agent 
	*/
    set @profile_id = NULL
    set @profile_name = formatmessage(20545) -- Default Distribution Profile
    set @profile_desc = NULL

    exec @retcode = dbo.sp_add_agent_profile
            @profile_id = @profile_id OUT,
            @profile_name = @profile_name,
            @agent_type = 3,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
            @profile_type = 0,   -- 0-System, 1-Custom 
            @description = @profile_desc,
            @default = 1
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    exec @retcode = dbo.sp_generate_agent_parameter @profile_id
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    /*
	** Distribution Agent Verbose History Profile
	*/
    set @profile_id = NULL
    set @profile_name = formatmessage(20546) -- Distribution Verbose History Profile
    set @profile_desc = formatmessage(20547)

    exec @retcode = dbo.sp_add_agent_profile
            @profile_id = @profile_id OUT,
            @profile_name = @profile_name,
            @agent_type = 3,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
            @profile_type = 0,   -- 0-System, 1-Custom 
            @description = @profile_desc,
            @default = 0
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    exec @retcode = dbo.sp_generate_agent_parameter @profile_id
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE
 
    /* 
	** Merge agent : Default profile for well connected scenarios 
	*/
    set @profile_id = NULL
    set @profile_name = formatmessage(20545) -- Default Merge Profile
    set @profile_desc = NULL

    exec @retcode = dbo.sp_add_agent_profile
            @profile_id = @profile_id OUT,
            @profile_name = @profile_name,
            @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
            @profile_type = 0,   -- 0-System, 1-Custom 
            @description = @profile_desc,
            @default = 1

    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    exec @retcode = dbo.sp_generate_agent_parameter @profile_id
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    /* 
	** Merge agent : Non default profile for disconnected scenarios ( unreliable link ) 
	*/
    set @profile_id = NULL
    set @profile_name = formatmessage(20548) -- Non-Default Merge Profile
    set @profile_desc = formatmessage(20549)

    exec @retcode = dbo.sp_add_agent_profile
            @profile_id = @profile_id OUT,
            @profile_name = @profile_name,
            @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
            @profile_type = 0,   -- 0-System, 1-Custom 
            @description = @profile_desc,
            @default = 0

    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    exec @retcode = dbo.sp_generate_agent_parameter @profile_id
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    /* 
	** Merge agent : Non default profile for verbose histroy
	*/
    set @profile_id = NULL
    set @profile_name = formatmessage(20546) -- Verbose Merge Profile
    set @profile_desc = formatmessage(20547)

    exec @retcode = dbo.sp_add_agent_profile
            @profile_id = @profile_id OUT,
            @profile_name = @profile_name,
            @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
            @profile_type = 0,   -- 0-System, 1-Custom 
            @description = @profile_desc,
            @default = 0

    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    exec @retcode = dbo.sp_generate_agent_parameter @profile_id
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    /* 
	** Merge agent : Synchronization Manager Profile
	*/
    set @profile_id = NULL
    set @profile_name = formatmessage(20550) -- SyncMgr Profile
    set @profile_desc = formatmessage(20551)

    exec @retcode = dbo.sp_add_agent_profile
            @profile_id = @profile_id OUT,
            @profile_name = @profile_name,
            @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
            @profile_type = 0,   -- 0-System, 1-Custom 
            @description = @profile_desc,
            @default = 0

    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    exec @retcode = dbo.sp_generate_agent_parameter @profile_id
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    /* 
	** Distribution agent : Synchronization Manager Profile
	*/
    set @profile_id = NULL
    set @profile_name = formatmessage(20550) -- SyncMgr Profile
    set @profile_desc = formatmessage(20551)

    exec @retcode = dbo.sp_add_agent_profile
            @profile_id = @profile_id OUT,
            @profile_name = @profile_name,
            @agent_type = 3,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
            @profile_type = 0,   -- 0-System, 1-Custom 
            @description = @profile_desc,
            @default = 0

    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE

    exec @retcode = dbo.sp_generate_agent_parameter @profile_id
    if (@retcode = 1 or @@ERROR <> 0)
        goto FAILURE


    create table msdb.dbo.MSdatatype_mappings 
    (
    dbms_name           sysname NOT NULL,
    sql_type            sysname NOT NULL,
    dest_type           sysname NOT NULL,
    dest_prec           int     NOT NULL,
    dest_create_params  int     NOT NULL,
    dest_nullable       bit     NOT NULL
    )

    exec dbo.sp_add_datatype_mapping 'MS Jet', 'binary' , 'binary', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'varbinary' , 'varbinary', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'binary' , 'image', 1073741824, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'varbinary' , 'image', 1073741824, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'varchar' , 'varchar', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'varchar' , 'longtext', 1073741824, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'nchar' , 'nchar', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'nchar' , 'longtext', 1073741824, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'char' , 'char', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'char' , 'longtext', 1073741824, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'nvarchar' , 'nchar varying', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'nvarchar' , 'longtext', 1073741824, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'datetime' , 'datetime', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'smalldatetime' , 'datetime', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'decimal' , 'decimal', 255, 3, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'numeric' , 'decimal', 255, 3, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'float' , 'float', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'real' , 'real', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'int' , 'int', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'smallint' , 'smallint', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'tinyint' , 'byte', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'money' , 'currency', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'smallmoney' , 'currency', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'bit' , 'bit', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'sysname' , 'nchar varying', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'timestamp' , 'binary', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'uniqueidentifier' , 'guid', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'text' , 'longtext', 1073741824, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'ntext' , 'longtext', 1073741824, 0, 1
    exec dbo.sp_add_datatype_mapping 'MS Jet', 'image' , 'image', 1073741824, 0, 1

    exec dbo.sp_add_datatype_mapping 'Oracle', 'binary' , 'raw', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'varbinary' , 'raw', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'binary' , 'long raw', 2147483647, 0, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'varbinary' , 'long raw', 2147483647, 0, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'varchar' , 'char', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'varchar' , 'varchar2', 2000, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'varchar' , 'long', 2147483647, 0, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'nchar' , 'char', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'nchar' , 'varchar2', 2000, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'nchar' , 'long', 2147483647, 0, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'char' , 'char', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'char' , 'varchar2', 2000, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'char' , 'long', 2147483647, 0, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'nvarchar' , 'char', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'nvarchar' , 'varchar2', 2000, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'nvarchar' , 'long', 2147483647, 0, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'datetime' , 'char', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'smalldatetime' , 'date', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'decimal' , 'number', 255, 3, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'numeric' , 'number', 255, 3, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'float' , 'float', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'real' , 'float', 255, 0, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'int' , 'number', 255, 3, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'smallint' , 'number', 255, 3, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'tinyint' , 'number', 255, 3, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'money' , 'number', 255, 3, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'smallmoney' , 'number', 255, 3, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'bit' , 'number', 255, 3, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'sysname' , 'char', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'timestamp' , 'raw', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'uniqueidentifier' , 'char', 255, 4, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'text' , 'long', 2147483647, 0, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'ntext' , 'long', 2147483647, 0, 1
    exec dbo.sp_add_datatype_mapping 'Oracle', 'image' , 'long raw', 2147483647, 0, 1

    return 0
FAILURE:
    return 1
go

dump tran master with no_log
GO

/*
** Create replication stored procedures.
** Part 2:  create all other stored procedures.
*/

raiserror('Creating procedure sp_MSIfExistsRemoteLogin', 0,1)
GO

CREATE proc sp_MSIfExistsRemoteLogin
    @remotesrvname sysname,
    @locallgname   sysname,
    @remotelgname  sysname
AS
begin


    if (@locallgname IS NULL)
    begin
     IF EXISTS (SELECT * FROM master.dbo.sysremotelogins srl, master.dbo.sysservers ss
                 WHERE UPPER(ss.srvname) = UPPER(@remotesrvname) AND 
                       srl.remoteserverid = ss.srvid AND 
                       (srl.remoteusername = @remotelgname OR 
                       (srl.remoteusername IS NULL AND srl.sid = 0x2)))
        return (1)
    else
        return (0)
    end

    if exists (SELECT * FROM master.dbo.sysremotelogins srl, master.dbo.sysservers ss 
                                WHERE UPPER(ss.srvname) = UPPER(@remotesrvname) AND 
                                      srl.remoteserverid = ss.srvid AND 
                                      srl.remoteusername = @remotelgname AND 
                                      srl.sid = suser_sid(@locallgname))
        return (1)
    else
        return (0)
end
go

raiserror('Creating procedure sp_helppublicationsync', 0,1)
GO

CREATE PROCEDURE sp_helppublicationsync (
        @publication sysname    /* The publication name */
        ) AS
    SET NOCOUNT ON
    RAISERROR (21023, 16, -1,'sp_helppublicationsync')
    RETURN(1)
GO

raiserror('Creating procedure sp_MSreplrole', 0,1)
GO
create procedure sp_MSreplrole
@name sysname,
@operation nvarchar(4)
as
declare @retcode int
-- Add/Drop when proper.
if @operation = 'add'
begin
    if user_id(@name) is null
    begin
        exec @retcode = dbo.sp_addrole @name
        IF @@ERROR <> 0 or @retcode <> 0
            RETURN (1)
    end
end
else if @operation = 'drop' 
begin
    if user_id(@name) is not null
    begin
        exec @retcode = dbo.sp_droprole @name
        IF @@ERROR <> 0 or @retcode <> 0
            RETURN (1)
    end
end
go


/* Create  sp_replicationdboption */
raiserror('Creating procedure sp_replicationdboption', 0,1)
GO

CREATE PROCEDURE sp_replicationdboption (
      @dbname    sysname,
      @optname   sysname,
      @value     sysname,
      @ignore_distributor bit = 0
    ) AS

    SET NOCOUNT ON

    /*
    ** Declarations.
    */
    
    declare @alert_name     sysname
    declare @alert_id       int
    declare @command        nvarchar(255)
    declare @description    nvarchar(500)
    declare @category_name  sysname
    declare @agentname      sysname
    DECLARE @retcode        int
    DECLARE @optbit         int
    DECLARE @optbit_value   int /* Desired value with the optbit mask */
    DECLARE @proc           nvarchar(255)

    /*
    ** Initialization
    */

    /*
    ** Parameter check
    ** @dbname
    */
    IF NOT EXISTS (SELECT * FROM master.dbo.sysdatabases WHERE
        name = @dbname)
    BEGIN
        RAISERROR(15010, 16, -1, @dbname)
        RETURN(1)
    END

    /*
    ** Parameter check
    ** @type
    */
    IF LOWER(@optname) NOT IN ('publish',
        'merge publish')
    BEGIN
        RAISERROR(14138,16,-1)
        RETURN(1)
    END

    /*
    ** Parameter check
    ** @value
    */
    IF LOWER(@value) NOT IN ('true','false')
    BEGIN
      RAISERROR(14137,16,-1)
      RETURN(1)
    END

    /*
    **  If we're in a transaction, disallow this since it might make recovery
    **  impossible.
    **
    */
    IF @@trancount > 0 
    BEGIN
        RAISERROR(15002,16,-1,'sp_replicationdboption')
        RETURN(1)
    END
    
    IF LOWER(@optname) = 'publish'
        BEGIN
            SELECT @optbit = 1
            SELECT @proc = QUOTENAME(@dbname) + '.dbo.sp_MSpublishdb'
        END
    ELSE IF LOWER(@optname) = 'merge publish'
        BEGIN
            SELECT @optbit = 4
            SELECT @proc = QUOTENAME(@dbname) + '.dbo.sp_MSmergepublishdb'
        END

    IF LOWER(@value) = 'true'
        SELECT @optbit_value = @optbit
    ELSE
        SELECT @optbit_value = 0

          
    /*
    ** Check if the option is set as required already
    */
    IF EXISTS (SELECT * FROM master..sysdatabases
        WHERE name = @dbname
        AND (category & @optbit) = @optbit_value)
    BEGIN
        if LOWER(@value) = 'true'
            RAISERROR (14035, 10, -1, @optname, @dbname)        
        else
            RAISERROR (14037, 10, -1, @optname, @dbname)
        RETURN (1)
    END

    /*
    ** Prepare the required option
    */
    EXEC @retcode = @proc @value = @value,
        @ignore_distributor = @ignore_distributor
    IF @@ERROR <> 0 or @retcode <> 0
    BEGIN
        GOTO UNDO
    END


    /*
    ** Preparation succeeded. 
    ** Toggle the category bit in master..sysdatabases
    */
    UPDATE master..sysdatabases SET category = category ^ @optbit
    WHERE name = @dbname
    IF @@ERROR <> 0 
    BEGIN
        GOTO UNDO
    END

	-- Get expired subscription cleanup agent name
    set @agentname = formatmessage(20569)  

    IF ((LOWER(@optname) = 'merge publish') or (LOWER(@optname) = 'publish')) and (LOWER(@value) = 'true')
    BEGIN
        IF NOT EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @agentname and originating_server = '(local)')
            BEGIN
                SELECT @command =  'EXEC dbo.sp_expired_subscription_cleanup'
            
                set @description = formatmessage(20542)
    
                select @category_name = name FROM msdb.dbo.syscategories where category_id = 17   
                
                EXECUTE @retcode = msdb.dbo.sp_MSadd_repl_job @agentname,
                @subsystem = 'TSQL',
                @server = @@SERVERNAME,
                @databasename = @dbname,
                @description = @description,
                @freqtype = 4,        -- daily
                @activestarttimeofday=010000,   -- from 01:00:00 am
                @command = @command,
                @enabled = 1,
                @retryattempts = 0,
                @loghistcompletionlevel = 0,
                @category_name = @category_name
            
                IF @@ERROR <> 0 or @retcode <> 0
                    BEGIN
                         return (1)
                    END
            END

		-- Expired subscription cleanup alert            
        select @category_name = name FROM msdb.dbo.syscategories where category_id = 20
        set @alert_name = formatmessage(20538)  
        set @alert_id = 14157 -- corresponding to formatmessage(20538)
        if not exists (select * from msdb.dbo.sysalerts where message_id = @alert_id)
        begin
            exec @retcode = msdb.dbo.sp_add_alert @enabled = 0, @name = @alert_name, @category_name = @category_name, @message_id = 14157
            if @@error <> 0 or @retcode <> 0
                goto UNDO
        end
    END

    IF ((LOWER(@optname) = 'merge publish') or (LOWER(@optname) = 'publish')) and (LOWER(@value) = 'false')
    BEGIN
            IF (EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @agentname and originating_server = '(local)')) 
                and (NOT exists (select name from master..sysdatabases where category & 4 =4 ))
                and (NOT exists (select name from master..sysdatabases where category & 1 =1))
        BEGIN
            EXEC @retcode = msdb.dbo.sp_delete_job  @job_name = @agentname
            IF @@ERROR <> 0 or @retcode <> 0
                return (1)            
        END
        
        set @alert_id = 14157 -- cleanup  alert
        set @alert_name = formatmessage(20569)
        if exists (select * from msdb.dbo.sysalerts where message_id=@alert_id)
            and (NOT exists (select name from master..sysdatabases where category & 4 =4 ))
                and (NOT exists (select name from master..sysdatabases where category & 1 =1))
        begin
            select @alert_name=name from msdb.dbo.sysalerts where message_id=@alert_id
            exec @retcode = msdb.dbo.sp_delete_alert @alert_name
            if @@error <> 0 or @retcode <> 0
                return (1)            
        end
    END
    
    /*
    **  ??? 
    ** CHECKPOINT the database that was changed. Make the change
    ** effective immediatly
    */
    CHECKPOINT
    IF @@ERROR <> 0 
    BEGIN
        RETURN(1)
    END

    RETURN(0)

UNDO:
    -- Create system table is not allowed in a multi-statement transactions.
    -- Drop the tables here
    IF LOWER(@value) = 'true'
        EXEC dbo.sp_replicationdboption 
          @dbname    = @dbname,
          @optname   = @optname,
          @value     = 'false',
          @ignore_distributor = @ignore_distributor

    return(1)   
GO
 

dump tran master with no_log
GO

raiserror('Creating procedure sp_addpublication_snapshot', 0,1)
GO

CREATE PROCEDURE sp_addpublication_snapshot (
    @publication sysname,    
    @frequency_type  int = 4 ,              /* 4== Daily */
    @frequency_interval int = 1,            /* Every day */
    @frequency_subday int = 4,              /* Sub interval = Minute */
    @frequency_subday_interval int = 5,     /* Every five minutes */
    @frequency_relative_interval int = 1, 
    @frequency_recurrence_factor int = 0, 
    @active_start_date int = 0, 
    @active_end_date int = 99991231 , 
    @active_start_time_of_day int = 0, 
    @active_end_time_of_day int = 235959         
) AS

    SET NOCOUNT ON

    /*
    ** Declarations.
    */
    DECLARE @retcode                int
    DECLARE @newid                  int
    DECLARE @mergepublish_bit       smallint
    DECLARE @transpublish_bit       int
    DECLARE @transpub_found         bit
    DECLARE @mergepub_found         bit
    DECLARE @newagentid             int

    /*
    ** Initializations
    */
    select @mergepublish_bit    = 4
    select @transpublish_bit    = 1
    select @transpub_found      = 0
    select @mergepub_found      = 0
    
	/*
	** Parameter Check
	*/
	exec @retcode = dbo.sp_MSreplcheck_name @publication
    if @@ERROR <> 0 or @retcode <> 0
        return(1)

    /*
    ** Security Check
    */
    exec @retcode = dbo.sp_MSreplcheck_publish
    if @@ERROR <> 0 or @retcode <> 0
        return(1)

    /*
    **  Check if the publication is valid.
    **  1. Check transaction-level publications
    **  2. Check merge publications
    */
    if (select category & @transpublish_bit from master..sysdatabases where name = DB_NAME()) <> 0
    begin
        EXEC @retcode = dbo.sp_MSaddpub_snapshot     @publication ,    
            @frequency_type,  
            @frequency_interval, 
            @frequency_subday, 
            @frequency_subday_interval,
            @frequency_relative_interval, 
            @frequency_recurrence_factor, 
            @active_start_date, 
            @active_end_date, 
            @active_start_time_of_day, 
            @active_end_time_of_day,         
            @newagentid OUTPUT

        IF @retcode <> 0 and @@ERROR <> 0 
            BEGIN
                RETURN (1)
            END

        if @newagentid <> 0
            begin
                select @transpub_found = 1
                goto DONE
            end             

    end
    
    if (select category & @mergepublish_bit from master..sysdatabases where name = DB_NAME()) <> 0
    begin
        EXEC @retcode = dbo.sp_MSaddmergepub_snapshot     @publication ,    
            @frequency_type,  
            @frequency_interval, 
            @frequency_subday, 
            @frequency_subday_interval,
            @frequency_relative_interval, 
            @frequency_recurrence_factor, 
            @active_start_date, 
            @active_end_date, 
            @active_start_time_of_day, 
            @active_end_time_of_day,         
            @newagentid OUTPUT

        IF @retcode <> 0 and @@ERROR <> 0 
            BEGIN
                RETURN (1)
            END

        if @newagentid <> 0
            begin
                select @mergepub_found = 1
                goto DONE
            end             
    end

DONE:
    if @transpub_found = 0 and @mergepub_found = 0
    begin
        RAISERROR (15001, 11, -1, @publication)
        RETURN (1)
    end
    return (0)        
GO
 
raiserror('Creating procedure sp_MShelpobjectpublications', 0,1)
GO

create procedure sp_MShelpobjectpublications (@object_name sysname)
AS
    /*
    ** Declarations.
    */
    DECLARE @retcode                int
    DECLARE @mergepublish_bit       smallint
    DECLARE @transpublish_bit       int

    declare @object_id int

    /*
    ** Initializations
    */
    select @mergepublish_bit    = 4
    select @transpublish_bit    = 1
    select @object_id           = OBJECT_ID(@object_name)

    create table #helpobjpubs (
        publication     sysname     NOT NULL, 
        reptype         int             NOT NULL, 
        article         sysname     NOT NULL, 
        article_type    int             NULL, 
        column_tracking int             NULL, 
        article_resolver nvarchar(255)  NULL)
    /*
    **  1. Return the transactional publications that the table is involved in
    */
    if (select category & @transpublish_bit from master..sysdatabases where name = DB_NAME()) <> 0
    begin
        if exists (select * from sysarticles a, 
            syspublications p where a.pubid = p.pubid and a.objid = @object_id)
            begin
                insert into #helpobjpubs(publication, reptype, article, article_type) 
                    select p.name, 1, a.name, a.type  from sysarticles a, 
                        syspublications p where a.pubid = p.pubid and a.objid = @object_id
                IF @@ERROR <> 0 
                    BEGIN
                        select @retcode = 1
                        goto DONE
                    END
            end
    end
    /*
    **  2. Return the merge publications that the table is involved in
    */
    if (select category & @mergepublish_bit from master..sysdatabases where name = DB_NAME()) <> 0
    begin
        if exists (select * from sysmergearticles a, 
            sysmergepublications p where a.pubid = p.pubid and a.objid = @object_id)
            begin
                insert into #helpobjpubs (publication, reptype, article, article_type, column_tracking, article_resolver)
                    select p.name, 2, a.name, a.type, a.column_tracking, a.article_resolver 
                        from sysmergearticles a, sysmergepublications p 
                        where a.pubid = p.pubid and a.objid = @object_id
                IF @@ERROR <> 0 
                    BEGIN
                        select @retcode = 1
                        goto DONE
                    END
            end
    end
    select @retcode = 0

DONE:
    select * from #helpobjpubs
    drop table #helpobjpubs
    return (@retcode)
go

raiserror('Creating procedure sp_helpreplicationdb', 0,1)
GO

CREATE PROCEDURE sp_helpreplicationdb
        @dbname sysname = '%', @type sysname = 'pub'
    AS

    SET NOCOUNT ON

    /*
    ** Declarations.
    */

    DECLARE @retcode int, @typebit int

    if (lower(@type) like 'pub%')
       select @typebit = 1
    else if (lower(@type) like 'sub%')
       select @typebit = 2
    else
    begin
       raiserror(14091,-1,-1)
       return 1
    end

    /*
    ** Parameter Check:  @dbname.
    ** Check to make sure that the database name conforms to the rules
    ** for identifiers.
    */

    IF @dbname <> '%'
       BEGIN
          EXECUTE @retcode = dbo.sp_validname @dbname

          IF @@ERROR <> 0 OR @retcode <> 0
          RETURN (1)
       END

    /*
    ** Show databases with this option enabled.
    */

    SELECT name
      FROM master..sysdatabases
     WHERE name LIKE @dbname
       AND (category & @typebit) <> 0
go
 

raiserror('Creating procedure sp_helpdistributor', 0,1)
go

CREATE PROCEDURE sp_helpdistributor (
    @distributor sysname  = '%' OUTPUT, /* The distribution server name */
    @distribdb   sysname  = '%' OUTPUT, /* The distribution database */
    @directory   nvarchar(255) = '%' OUTPUT, /* The working directory */
    @account     nvarchar(255) = '%' OUTPUT, /* The Windows NT user account */
    @min_distretention int      = -1 OUTPUT, /* The min distribution retention */
    @max_distretention int      = -1 OUTPUT, /* The min distribution retention */
    @history_retention   int  = -1 OUTPUT, /* The history retention period */
    @history_cleanupagent nvarchar(100) = '%' OUTPUT, /* The history cleanup agent */
    @distrib_cleanupagent nvarchar(100) = '%' OUTPUT, /* The distribution cleanup agent */
    @publisher sysname = NULL,  /* Name of publisher */
    @local nvarchar(5) = NULL,        /* Get local server values */
    @rpcsrvname sysname = '%' OUTPUT
) AS
    SET NOCOUNT ON

    /*
    ** Declarations.
    */
    DECLARE @loc_distributor         sysname
    DECLARE @loc_distribdb             sysname
    DECLARE @loc_directory             nvarchar(255)
    DECLARE @loc_account             nvarchar(255)
    DECLARE @loc_mindistretention     int
    DECLARE @loc_maxdistretention     int
    DECLARE @loc_historyretention   int  
    DECLARE @loc_historycleanupagent nvarchar(100)
    DECLARE @loc_distribcleanupagent nvarchar(100)
    DECLARE @loc_security_mode  int  
    DECLARE @loc_login sysname
    DECLARE @loc_password sysname
    declare @loc_rpcsrvname sysname
    DECLARE @proc nvarchar(255)
    DECLARE @reg_key nvarchar (255)
    DECLARE @retcode int
    declare @rpcsrvlogin sysname
    declare @srvid smallint
    declare @dist_rpcname sysname
    declare @platform_nt binary

    select @platform_nt = 0x1

    IF @publisher IS NULL
    BEGIN
        /* 
        ** 6.x compatibility 
        ** If local is set, we know the call is from a publisher. 
        ** set it to be @@REMSERVER 
        ** Otherwise, set it to be local server name
        ** Note: @@REMSERVER is NULL for local sp calls 
        */
        IF LOWER(@local) = 'local' AND @@REMSERVER IS NOT NULL
            SELECT @publisher = @@REMSERVER
        ELSE
            SELECT  @publisher = @@SERVERNAME
    END

    /*
    ** Get the distribution server
    */
    SELECT @dist_rpcname = srvname, @loc_distributor = datasource, @srvid = srvid, @loc_rpcsrvname = srvname
        FROM master..sysservers
        WHERE srvstatus & 8 <> 0
    
    if @loc_distributor is null
        GOTO DONE

    select @rpcsrvlogin = name from master.dbo.sysxlogins where
        srvid = @srvid and sid is NULL

    /*
    ** If remote distribuiton, execute dbo.sp_helpdistributor on distribution
    ** server.
    */
    IF UPPER(@loc_distributor) <> UPPER(@@SERVERNAME)
    BEGIN
        SELECT @proc = @dist_rpcname + '.master.dbo.sp_helpdistributor'
        EXECUTE @retcode = @proc
            @loc_distributor OUTPUT,
            @loc_distribdb OUTPUT,
            @loc_directory OUTPUT,
            @loc_account OUTPUT,
            @loc_mindistretention OUTPUT,
            @loc_maxdistretention OUTPUT,
            @loc_historyretention OUTPUT,
            @loc_historycleanupagent OUTPUT,
            @loc_distribcleanupagent OUTPUT,
            @@SERVERNAME,
            @local = 'local'
        IF @retcode <> 0 or @@ERROR <> 0
           RETURN (1)

            GOTO DONE
    END

    SELECT  @loc_distribdb = distribution_db,
            @loc_directory = working_directory
        FROM msdb.dbo.MSdistpublishers WHERE UPPER(name) = UPPER(@publisher)

    IF @@ERROR <> 0
        RETURN 1 ;

    SELECT  @loc_mindistretention = min_distretention,      
            @loc_maxdistretention = max_distretention,
            @loc_historyretention = history_retention
        FROM msdb.dbo.MSdistributiondbs WHERE name = @loc_distribdb 

    /*
    ** Fetch the distribution account name.
    */
    IF ((@distributor = '%' AND @distribdb = '%' AND @directory = '%'
    AND @account = '%' AND @min_distretention = -1 AND @max_distretention = -1 
    AND @history_retention = -1 AND @history_cleanupagent = '%' 
    AND @distrib_cleanupagent = '%' ) 
    OR @account IS NULL) and ( platform() & @platform_nt = @platform_nt ) 
       BEGIN
        SELECT @proc = 'master..xp_regread'
        EXECUTE @retcode = @proc 'HKEY_LOCAL_MACHINE',
              'SYSTEM\CurrentControlSet\Services\SQLServerAgent',
              'ObjectName',
            @param = @loc_account OUTPUT
    
        IF @@ERROR <> 0 OR @retcode <> 0
            SELECT @loc_account = NULL
       END

    /*
    ** Fetch the history cleanup agentname.
    */
    IF @loc_distribdb IS NOT NULL
        SELECT @loc_historycleanupagent = formatmessage (20567, @loc_distribdb)

    /*
    ** Fetch the distribution cleanup agent name.
    */
    IF @loc_distribdb IS NOT NULL
        SELECT @loc_distribcleanupagent = formatmessage (20568, @loc_distribdb)


DONE:
    /*
    ** Return result set if no output parameters
    */

    IF @distributor = '%' AND @distribdb = '%' AND @directory = '%'
    AND @account = '%' AND @min_distretention = -1 AND @max_distretention = -1 
    AND @history_retention = -1 AND @history_cleanupagent = '%' 
    AND @distrib_cleanupagent = '%' AND @rpcsrvname = '%' 
    SELECT       'distributor'           = @loc_distributor,
               'distribution database' = @loc_distribdb,
               'directory'              = @loc_directory,
               'account'               = @loc_account,
               'min distrib retention' = @loc_mindistretention,
               'max distrib retention' = @loc_maxdistretention,
               'history retention'     = @loc_historyretention,
               'history cleanup agent'  = @loc_historycleanupagent,
               'distribution cleanup agent' = @loc_distribcleanupagent,
               'rpc server name' = @loc_rpcsrvname,
               'rpc login name' = @rpcsrvlogin

    /*
    ** Return output parameters if requested.
    */

    IF @distributor IS NULL
        SELECT @distributor = @loc_distributor
    IF @distribdb IS NULL
        SELECT @distribdb = @loc_distribdb
    IF @directory IS NULL
        SELECT @directory = @loc_directory
    IF @account IS NULL
        SELECT @account = @loc_account
    IF @min_distretention IS NULL
        SELECT @min_distretention = @loc_mindistretention
    IF @max_distretention IS NULL
        SELECT @max_distretention = @loc_maxdistretention
    IF @history_retention IS NULL
        SELECT @history_retention = @loc_historyretention
    IF @history_cleanupagent IS NULL
        SELECT @history_cleanupagent = @loc_historycleanupagent
    IF @distrib_cleanupagent IS NULL
        SELECT @distrib_cleanupagent = @loc_distribcleanupagent
   
    IF @rpcsrvname IS NULL
    begin
        -- Use local RPC if possible to avoid blocking problem.
        if is_srvrolemember('sysadmin') = 1 and UPPER(@loc_distributor) = UPPER(@@servername)
            select @rpcsrvname = @@servername
        else
            select @rpcsrvname = @loc_rpcsrvname
    end
  
    RETURN (0)
GO
 
dump tran master with no_log
go

raiserror('Creating procedure sp_enumdsn', 0,1)
GO

CREATE PROCEDURE sp_enumdsn
    AS

    SET NOCOUNT ON

    DECLARE @distributor sysname
    DECLARE @distproc nvarchar (255)
    DECLARE @retcode int

    DECLARE @dsotype_odbc int
    DECLARE @dsotype_oledb int

    select @dsotype_odbc = 1
    select @dsotype_oledb = 3

    /*
    ** Get distribution server information for remote RPC
    ** subscription calls.
    */

    EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT
    IF @@error <> 0 OR @retcode <> 0 or @distributor is null
        BEGIN
        RAISERROR (14071, 16, -1)
            RETURN (1)
    END

    create table #datasourcestemptable (DataSourceName sysname not null, Description varchar(255) null, DataSourceType int null, ProviderName varchar(255) null)
    
    /*
    ** Call xp_enumdsn
    */
    SELECT @distproc = RTRIM(@distributor) + '.master..xp_enumdsn'
    insert into #datasourcestemptable(DataSourceName, Description) EXEC @retcode = @distproc
    IF @@error <> 0
        BEGIN
        RAISERROR (14071, 16, -1)
        RETURN (1)
    END

    update #datasourcestemptable set DataSourceType = @dsotype_odbc where DataSourceType is null
    IF @@error <> 0 
    BEGIN
        RETURN (1)
    END

    /*
    ** Call sp_enumoledbdatasources
    */
    SELECT @distproc = RTRIM(@distributor) + '.master.dbo.sp_enumoledbdatasources'
    insert into #datasourcestemptable(DataSourceName, Description, ProviderName) EXEC @retcode = @distproc
    IF @@error <> 0
        BEGIN
        RAISERROR (14071, 16, -1)
        RETURN (1)
    END

    update #datasourcestemptable set DataSourceType = @dsotype_oledb where DataSourceType is null
    IF @@error <> 0 
    BEGIN
        RETURN (1)
    END
    
    select 'Data Source Name' = DataSourceName, Description, 'Type' = DataSourceType, 'Provider Name' = ProviderName 
    from #datasourcestemptable
    order by 3, 1

    drop table #datasourcestemptable

    return (0)
go

raiserror('Creating procedure sp_enumoledbdatasources', 0,1)
GO

CREATE PROCEDURE sp_enumoledbdatasources
    AS
    set nocount on

    select srvname, srvproduct, providername from master..sysservers where 
    (srvstatus & 0x0080) <> 0

    return (0)
go

raiserror('Creating procedure sp_helpsubscriberinfo', 0,1)
GO

CREATE PROCEDURE sp_helpsubscriberinfo
    @subscriber sysname = '%'
    AS

    SET NOCOUNT ON

    DECLARE @distributor sysname
    DECLARE @distribdb sysname
    DECLARE @distproc nvarchar (255)
    DECLARE @retcode int
    DECLARE @subscriber_bit smallint
    DECLARE @show_password bit

    /*
    ** Security Check
    */

    /*
    ** Initializations.
    */
    SELECT @subscriber_bit = 4


    /*
    ** Check if subscriber is valid
    */

    IF @subscriber IS NULL
        BEGIN
            RAISERROR (14043, 16, -1, '@subscriber')
            RETURN (1)
        END


    IF @subscriber <> '%'
        BEGIN

            EXECUTE @retcode = dbo.sp_validname @subscriber
            IF @retcode <> 0
                RETURN (1)

            IF NOT EXISTS (SELECT *
                        FROM master..sysservers
                        WHERE UPPER(srvname) = UPPER(@subscriber)
                        AND (srvstatus & @subscriber_bit) <> 0)
                BEGIN
                    RAISERROR (14010, 16, -1)
                    RETURN (1)
                END
        END


    /*
    ** Get distribution server information for remote RPC
    ** subscription calls.
    */

    EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
                                       @distribdb   = @distribdb OUTPUT

    /* RAISEERROR is subscriber is not '%' */                                               
    IF @@error <> 0 OR @retcode <> 0 OR @distribdb IS NULL OR @distributor IS NULL
        BEGIN
        IF @subscriber <> '%'
            BEGIN
                RAISERROR (14071, 16, -1)
                RETURN (1)
            END
        ELSE
            RETURN 0
        END

     create table #subscriber_info
     (
        publisher  sysname not null,
        subscriber  sysname not null,
        type tinyint not null,           /* 0: MS SQL Server 1: ODBC Data Source */
        login sysname NULL, 
        password sysname NULL,
        commit_batch_size int not null,  -- commit_batch_size, no longer supported
        status_batch_size int not null,  -- status_batch_size, no longer supported
        flush_frequency int not null,  -- flush_frequency, no longer supported
        frequency_type int not null,
        frequency_interval int not null,
        frequency_relative_interval int not null,
        frequency_recurrence_factor int not null,
        frequency_subday int not null,
        frequency_subday_interval int not null,
        active_start_time_of_day int not null,
        active_end_time_of_day int not null,
        active_start_date int not null,
        active_end_date int not null,
        retryattempt    int not null, -- retryattempt, no longer exist
        retrydelay  int not null,  -- retrydelay, no longer exist
        description nvarchar(255) NULL,
        security_mode int not null,
        frequency_type2 int not null,
        frequency_interval2 int not null,
        frequency_relative_interval2 int not null,
        frequency_recurrence_factor2 int not null,
        frequency_subday2 int not null,
        frequency_subday_interval2 int not null,
        active_start_time_of_day2 int not null,
        active_end_time_of_day2 int not null,
        active_start_date2 int not null,
        active_end_date2 int not null
    )

    IF @@error <> 0
        RETURN (1)
     
    /*
    ** Retrieve MSsubscriber_info
    */
    if is_srvrolemember('sysadmin') = 1
        select @show_password = 1
    else
        select @show_password = 0

    SELECT @distproc = RTRIM(@distributor) + '.' +
        RTRIM(@distribdb) + '.dbo.sp_MShelp_subscriber_info'

    insert into #subscriber_info EXEC @retcode = @distproc 
        @publisher = @@SERVERNAME, 
        @subscriber = @subscriber,
        @show_password = [REDACTED]

    IF @@error <> 0
        BEGIN
        RAISERROR (14071, 16, -1)
        RETURN (1)
    END

    IF @retcode <> 0
        BEGIN
        RAISERROR (14085, 16, -1)
        RETURN (1)
     END

    -- Filter out subscribers that are not defined locally but left at the distributor
    -- This will happen if the publisher is cleaned up when the distributor is offline.
    select info.* from #subscriber_info info, master..sysservers servers where
        UPPER(info.subscriber) = UPPER(servers.srvname) and
        (servers.srvstatus & @subscriber_bit) <> 0

go
 
raiserror('Creating procedure sp_replica', 0,1)
GO

CREATE PROCEDURE sp_replica (
        @tabname nvarchar(92),     /* The table being replicated */
        @replicated nvarchar(5)    /* True or false */
        ) AS

    SET NOCOUNT ON
    RAISERROR (21023, 16, -1,'sp_replica')
    RETURN(1)
go
 

dump tran master with no_log
go

raiserror('Creating procedure sp_addpublisher', 0,1)
GO

CREATE PROCEDURE sp_addpublisher (
    @publisher sysname,      /* publisher server name */
    @type nvarchar (5) = NULL     /* NULL or 'dist' */
 ) AS

    SET NOCOUNT ON
    RAISERROR (21023, 16, -1,'sp_addpublisher')
    RETURN(1)
go
 
raiserror('Creating procedure sp_addsubscriber', 0,1)
GO

CREATE PROCEDURE sp_addsubscriber (
    @subscriber sysname,
    @type tinyint = 0,
    @login sysname = 'sa',
    @password sysname = NULL,
    @commit_batch_size int = 100,
    @status_batch_size int = 100,
    @flush_frequency int = 0,
    @frequency_type int = 64,
    @frequency_interval int = 1,
    @frequency_relative_interval int = 1,
    @frequency_recurrence_factor int = 0,
    @frequency_subday int = 4,
    @frequency_subday_interval int = 5,
    @active_start_time_of_day int = 0,
    @active_end_time_of_day int = 235959,
    @active_start_date int = 0,
    @active_end_date int = 99991231,
    @description nvarchar (255) = NULL,
    @security_mode int = 1,  /* backward compatible */ /* 0 standard; 1 integrated */
    @encrypted_password bit = 0
        ) AS

    DECLARE @distributor sysname
    DECLARE @distribdb sysname
    DECLARE @distproc nvarchar (255)
    DECLARE @retcode int
    DECLARE @dsn_subscriber tinyint
    DECLARE @jet_subscriber tinyint
    DECLARE @oledb_subscriber tinyint
    DECLARE @dist_rpcname sysname
    DECLARE @platform_nt binary

    -- Defined in sqlrepl.h
    select @dsn_subscriber = 1    /* Const: subscriber type 'dsn' */ 
    select @jet_subscriber = 2   
    select @oledb_subscriber = 3  
    
    select @platform_nt = 0x1

    /* 
    ** Check if replication components are installed on this server
    */
    exec @retcode = dbo.sp_MS_replication_installed
    if (@retcode <> 1)
    begin
        return (1)
    end
    
    /*
    ** Parameter Check:  @subscriber.
    ** Check to make sure that the subscriber doesn't already exist, and
    ** that the name is a valid non-null identifier.
    */

    IF @subscriber IS NULL
        BEGIN
            RAISERROR (14043, 16, -1, '@subscriber')
            RETURN (1)
        END

    EXECUTE @retcode = dbo.sp_validname @subscriber

    IF @@ERROR <> 0 OR @retcode <> 0
    RETURN (1)

    if LOWER(@subscriber) = 'all'
        BEGIN
            RAISERROR (14032, 16, -1, '@subscriber')
            RETURN (1)
        END

    /* 
    ** Check for invalid security mode
    */
    IF @security_mode < 0 OR @security_mode > 1
        BEGIN
            RAISERROR(14109, 16, -1)
            RETURN (1)
        END

    IF (UPPER(@subscriber) = UPPER(@@SERVERNAME) and @platform_nt != ( platform() & @platform_nt ) and @security_mode = 1)
        BEGIN
            RAISERROR(21038, 16, -1)
            RETURN (1)
        END

    IF EXISTS (SELECT *
                 FROM master..sysservers
                WHERE UPPER(srvname) = UPPER(@subscriber)
                  AND srvstatus & 4 <> 0)

        BEGIN
            RAISERROR (14040, 16, -1, @subscriber)
            RETURN (1)
        END

	IF @password = N''
		select @password = [REDACTED]

    
    /*
    **  If no MSsubscriber_info parameters skip RPC code.
    */

    IF @frequency_type = -1
        GOTO ADDSUB

    /*
    ** Get distribution server information for remote RPC
    ** subscription calls.
    */

 /*   BEGIN TRAN addsubscriber */

    EXEC @retcode = dbo.sp_helpdistributor  @distributor = @distributor OUTPUT,
                                        @rpcsrvname = @dist_rpcname OUTPUT,
                                        @distribdb   = @distribdb   OUTPUT

    IF @@error <> 0
        BEGIN
         RAISERROR (14071, 16, -1)
         goto undo
     END

    IF @retcode <> 0 OR @distribdb IS NULL OR @distributor IS NULL
        BEGIN
            RAISERROR (14071, 16, -1)
            goto undo
        END


    DECLARE @zeroint int
    SELECT @zeroint = 0
    /*
    ** Insert information into MSsubscriber_info
    */
    SELECT @distproc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSadd_subscriber_info'
    EXEC @retcode = @distproc
         @@SERVERNAME,
         @subscriber,
     @type,
     @login,
     @password,
     @commit_batch_size,
     @status_batch_size,
     @flush_frequency,
     @frequency_type,
     @frequency_interval,
     @frequency_relative_interval,
     @frequency_recurrence_factor,
     @frequency_subday,
     @frequency_subday_interval,
     @active_start_time_of_day,
     @active_end_time_of_day,
     @active_start_date,
     @active_end_date,
     /* Work around of server RPC  named parameter problem */
     @retryattempts = @zeroint,
     @retrydelay  = @zeroint,
     @description = @description,
     @security_mode = @security_mode,
     @encrypted_password = [REDACTED]

    IF @@error <> 0 OR @retcode <> 0
        BEGIN
        RAISERROR (14042, 16, -1)
        goto undo
    END

    /*
    ** add schedule information into MSsubscriber_schedule for merge agent
    */
    -- NOTE: We may need better default schedule for merge agent
    
    SELECT @distproc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSadd_subscriber_schedule'
    EXEC @retcode = @distproc
         @@SERVERNAME,
         @subscriber,
         0, -- agent_type = 0 means distribution agent
         @frequency_type,
         @frequency_interval,
         @frequency_relative_interval,
         @frequency_recurrence_factor,
         @frequency_subday,
         @frequency_subday_interval,
         @active_start_time_of_day,
         @active_end_time_of_day,
         @active_start_date,
         @active_end_date
    
    IF @@error <> 0 OR @retcode <> 0
        BEGIN
            RAISERROR (14042, 16, -1)
            goto undo
        END

    EXEC @retcode = @distproc
         @@SERVERNAME,
         @subscriber,
         1,             --agent_type = 0 means merge agent
         4,             --frequency_type,
         1,             --frequency_interval,
         1,             --frequency_relative_interval,
         0,             --frequency_recurrence_factor,
         8,             --frequency_subday,
         1,             --frequency_subday_interval,
         0,             --active_start_time_of_day,
         235959,        --active_end_time_of_day,
         0,             --active_start_date,
         99991231       --active_end_date
    
    IF @@error <> 0 OR @retcode <> 0
        BEGIN
            RAISERROR (14042, 16, -1)
            goto undo
        END

/*    Commit Transaction addsubscriber */

ADDSUB:

    /*
    ** The server may already be listed in master..sysservers, but might
    ** not be marked as a subscriber yet.  If it's not in
    ** master..sysservers, let's add it first.
    */

    IF NOT EXISTS (SELECT *
                         FROM master..sysservers
                        WHERE LOWER(srvname) = LOWER(@subscriber))
    begin

        EXECUTE @retcode = dbo.sp_addserver @subscriber

            IF @@error <> 0 OR @retcode <> 0
                BEGIN
                RAISERROR (14042, 16, -1)
                    RETURN (1)
                END
    end
    /*
    ** Set the server option to indicate this is a subscriber.
    */

    EXECUTE @retcode = dbo.sp_serveroption @subscriber, 'sub', true

    IF @@error <> 0 OR @retcode <> 0
        BEGIN
           RAISERROR (14042, 16, -1)
           RETURN (1)
        END

    /*
    ** Set the server option to indicate this is a DSN subscriber.
    */
    if @type = @dsn_subscriber OR @type = @jet_subscriber OR @type = @oledb_subscriber
       BEGIN
          update master..sysservers set srvproduct = 'MSREPL-NONSQL' where
            UPPER(srvname) = UPPER(@subscriber)
          IF @@error <> 0 
            return(1)
       END
    
        RETURN (0) 
undo:

    RETURN (1) 
GO

raiserror('Creating procedure sp_addsubscriber_schedule', 0,1)
GO

CREATE PROCEDURE sp_addsubscriber_schedule (
    @subscriber sysname,
    @agent_type smallint = 0,
    @frequency_type int = 64,
    @frequency_interval int = 1,
    @frequency_relative_interval int = 1,
    @frequency_recurrence_factor int = 0,
    @frequency_subday int = 4,
    @frequency_subday_interval int = 5,
    @active_start_time_of_day int = 0,
    @active_end_time_of_day int = 235959,
    @active_start_date int = 0,
    @active_end_date int = 99991231
        ) AS

    DECLARE @distributor sysname
    DECLARE @distribdb sysname
    DECLARE @distproc nvarchar (255)
    DECLARE @retcode int
    DECLARE @msg nvarchar(255)
    
    /*
    ** Parameter Check:  @subscriber.
    ** Check to make sure that the subscriber doesn't already exist, and
    ** that the name is a valid non-null identifier.
    */

    IF @subscriber IS NULL
        BEGIN
            RAISERROR (14043, 16, -1, '@subscriber')
            RETURN (1)
        END

    EXECUTE @retcode = dbo.sp_validname @subscriber

    IF @@ERROR <> 0 OR @retcode <> 0
    RETURN (1)

    if LOWER(@subscriber) = 'all'
        BEGIN
            RAISERROR (14032, 16, -1, '@subscriber')
            RETURN (1)
        END

    IF NOT EXISTS (SELECT * FROM master..sysservers WHERE UPPER(srvname) = UPPER(@subscriber))
        BEGIN
            RAISERROR (14048, 16, -1, @subscriber)
            RETURN (1)
        END
    
    EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
                                       @distribdb   = @distribdb   OUTPUT

    IF @@error <> 0
        BEGIN
         RAISERROR (14071, 16, -1)
         RETURN (1)
     END

    IF @retcode <> 0 OR @distribdb IS NULL OR @distributor IS NULL
        BEGIN
            RAISERROR (14071, 16, -1)
            RETURN (1)
        END
    
    SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSadd_subscriber_schedule'
    EXEC @retcode = @distproc
         @@SERVERNAME,
         @subscriber,
         @agent_type,
         @frequency_type,
         @frequency_interval,
         @frequency_relative_interval,
         @frequency_recurrence_factor,
         @frequency_subday,
         @frequency_subday_interval,
         @active_start_time_of_day,
         @active_end_time_of_day,
         @active_start_date,
         @active_end_date
    
    IF @@error <> 0 OR @retcode <> 0
        BEGIN
        RAISERROR (14042, 16, -1)
        RETURN (1)
    END

    RETURN (0)
GO
 
raiserror('Creating procedure sp_changesubscriber', 0,1)
GO

CREATE PROCEDURE sp_changesubscriber (
    @subscriber sysname,
    @type tinyint = NULL,
    @login sysname = NULL,
    @password sysname = '%',
    @commit_batch_size int = NULL,
    @status_batch_size int = NULL,
    @flush_frequency int = NULL,
    @frequency_type int = NULL,
    @frequency_interval int = NULL,
    @frequency_relative_interval int = NULL,
    @frequency_recurrence_factor int = NULL,
    @frequency_subday int = NULL,
    @frequency_subday_interval int = NULL,
    @active_start_time_of_day int = NULL,
    @active_end_time_of_day int = NULL,
    @active_start_date int = NULL,
    @active_end_date int = NULL,
    @description nvarchar (255) = NULL,
    @security_mode int = NULL /* 0 standard; 1 integrated */

        ) AS

    DECLARE @distributor sysname
    DECLARE @distribdb sysname
    DECLARE @distproc nvarchar (255)
    DECLARE @msg nvarchar(255)
    DECLARE @retcode int
    DECLARE @platform_nt binary

    select @platform_nt = 0x1

    IF (UPPER(@subscriber) = UPPER(@@SERVERNAME) and @platform_nt != ( platform() & @platform_nt ) and @security_mode = 1)
        BEGIN
            RAISERROR(21038, 16, -1)
            RETURN (1)
        END

    /*
    ** Check to make sure that the subscriber exists.
    */
    IF NOT EXISTS (SELECT *
                 FROM master..sysservers
                WHERE UPPER(srvname) = UPPER(@subscriber))
        BEGIN
            RAISERROR(14048, 16, 1, @subscriber)
            RETURN (1)
        END

    /*
    ** Get distribution server information for remote RPC
    ** subscription calls.
    */
    EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
        @distribdb = @distribdb OUTPUT
    IF @@ERROR <> 0 OR @retcode <> 0
        BEGIN
            RAISERROR (14071, 16, -1)
            RETURN (1)
        END

    DECLARE @intnull int
    /*
    ** Update MSsubscriber_info
    */
    SELECT @distproc = RTRIM(@distributor) + '.' +
        RTRIM(@distribdb) + '.dbo.sp_MSupdate_subscriber_info'
    EXEC @retcode = @distproc
        @@SERVERNAME,
        @subscriber,
    @type,
    @login,
    @password,
    @commit_batch_size,
    @status_batch_size,
    @flush_frequency,
    @frequency_type,
    @frequency_interval,
    @frequency_relative_interval,
    @frequency_recurrence_factor,
    @frequency_subday,
    @frequency_subday_interval,
    @active_start_time_of_day,
    @active_end_time_of_day,
    @active_start_date,
    @active_end_date,
    @retryattempts = @intnull,
    @retrydelay  = @intnull,
    @description = @description,
    @security_mode = @security_mode
    IF @@ERROR <> 0 OR @retcode <> 0
        BEGIN
            RAISERROR (14048, 16, -1, @subscriber)
            RETURN (1)
    END
go
 
raiserror('Creating procedure sp_changesubscriber_schedule', 0,1)
GO

CREATE PROCEDURE sp_changesubscriber_schedule (
    @subscriber sysname,
    @agent_type smallint,
    @frequency_type int = NULL,
    @frequency_interval int = NULL,
    @frequency_relative_interval int = NULL,
    @frequency_recurrence_factor int = NULL,
    @frequency_subday int = NULL,
    @frequency_subday_interval int = NULL,
    @active_start_time_of_day int = NULL,
    @active_end_time_of_day int = NULL,
    @active_start_date int = NULL,
    @active_end_date int = NULL
        ) AS

    DECLARE @distributor sysname
    DECLARE @distribdb sysname
    DECLARE @distproc nvarchar (255)
    DECLARE @msg nvarchar(255)
    DECLARE @retcode int

    /*
    ** Check to make sure that the subscriber DOES exist.
    */
    IF NOT EXISTS (SELECT *
                 FROM master..sysservers
                WHERE UPPER(srvname) = UPPER(@subscriber))
        BEGIN
            RAISERROR (14048, 16, -1, @subscriber)
            RETURN (1)
        END

    /*
    ** Get distribution server information for remote RPC
    ** subscription calls.
    */
    EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
        @distribdb = @distribdb OUTPUT
    IF @@ERROR <> 0 OR @retcode <> 0
         BEGIN
            RAISERROR (14071, 16, -1)
             RETURN (1)
         END

    /*
    ** Update MSsubscriber_info
    */
    SELECT @distproc = RTRIM(@distributor) + '.' +
        RTRIM(@distribdb) + '.dbo.sp_MSupdate_subscriber_schedule'
    EXEC @retcode = @distproc
        @@SERVERNAME,
        @subscriber,
        @agent_type,
        @frequency_type,
        @frequency_interval,
        @frequency_relative_interval,
        @frequency_recurrence_factor,
        @frequency_subday,
        @frequency_subday_interval,
        @active_start_time_of_day,
        @active_end_time_of_day,
        @active_start_date,
        @active_end_date
    
    IF @@ERROR <> 0 OR @retcode <> 0
        BEGIN
            RAISERROR (14048, 16, -1, @subscriber)
            RETURN (1)
        END
        
    RETURN (0)  
go 
    
raiserror('Creating procedure sp_distcounters', 0,1)
GO

CREATE PROCEDURE sp_distcounters
    AS

    SET NOCOUNT ON

    /*
    ** Declarations.
    */
    DECLARE @distributor sysname
    DECLARE @distribdb sysname
    DECLARE @distproc nvarchar (255)
    DECLARE @retcode int

    /*
    ** Get distribution server information for remote RPC
    ** subscription calls.  If no distribution information, assume
    ** replication is not being used.
    */
    EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
                                       @distribdb = @distribdb OUTPUT
    IF @@error <> 0 OR @retcode <> 0 OR @distributor IS NULL OR
       @distribdb IS NULL
    RETURN (1)

    /*
    ** Request counters from Distribution Server
    */
    SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) +
    '.dbo.sp_MSdistribution_counters'
    EXEC @retcode = @distproc @@SERVERNAME
go
 

raiserror('Creating procedure sp_droppublisher', 0,1)
GO

CREATE PROCEDURE sp_droppublisher (
    @publisher sysname,         /* publisher server name */
    @type nvarchar (5) = NULL      /* NULL or 'dist' */
        ) AS

    SET NOCOUNT ON
    RAISERROR (21023, 16, -1,'sp_droppublisher')
    RETURN(1)

go
 
raiserror('Creating procedure sp_dropsubscriber', 0,1)
GO

CREATE PROCEDURE sp_dropsubscriber (
    @subscriber sysname,        /* The name of the subscriber */
    @reserved nvarchar(50) = NULL,
    @ignore_distributor bit = 0
        ) AS

    SET NOCOUNT ON

    /*
    ** Declarations.
    */

    DECLARE @db_name sysname
    DECLARE @foundSubscription int
    DECLARE @command nvarchar(255)
    DECLARE @transpublishdb_bit int
    DECLARE @mergepublishdb_bit int
    DECLARE @distributor sysname
    DECLARE @distribdb sysname
    DECLARE @distproc nvarchar (255)
    DECLARE @retcode int
    DECLARE @type nvarchar(10)

    SELECT @transpublishdb_bit = 1
    SELECT @mergepublishdb_bit = 4


    /*
    ** Parameter Check:  @subscriber.
    ** Check to make sure that the subscriber exists.
    */

    IF @subscriber IS NULL
        BEGIN
            RAISERROR (14043, 16, -1, '@subscriber')
            RETURN (1)
        END

    EXECUTE @retcode = dbo.sp_validname @subscriber

    IF @retcode <> 0
    RETURN (1)

    IF lower(@subscriber) <> 'all' and NOT EXISTS (SELECT *
                     FROM master..sysservers
                    WHERE UPPER(srvname) = UPPER(@subscriber)
                      AND srvstatus & 4 <> 0)

        BEGIN
            RAISERROR (14048, 16, -1, @subscriber)
            RETURN (1)
        END

    if lower(@subscriber) = 'all'
    begin
        DECLARE hCdropsubscriber_all CURSOR LOCAL FAST_FORWARD FOR
            SELECT srvname
                     FROM master..sysservers
                    WHERE srvstatus & 4 <> 0
        FOR READ ONLY
        OPEN hCdropsubscriber_all
        FETCH hCdropsubscriber_all INTO @subscriber
    
        WHILE (@@fetch_status <> -1)
        BEGIN
            EXECUTE @retcode  = dbo.sp_dropsubscriber
                @subscriber = @subscriber,    
                @ignore_distributor = @ignore_distributor,
                @reserved = @reserved
            IF @@ERROR <> 0 OR @retcode <> 0
            BEGIN
                CLOSE hCdropsubscriber_all
                DEALLOCATE hCdropsubscriber_all
                RETURN (1)
            END
            FETCH hCdropsubscriber_all INTO @subscriber
        end
        
        CLOSE hCdropsubscriber_all
        DEALLOCATE hCdropsubscriber_all

        return(0)
    end


    /*
    ** There should be no subscription by the subscriber
    ** Open a cursor the published databases.
    **
    */
    DECLARE hCdropsubscriber CURSOR LOCAL FAST_FORWARD FOR
            SELECT name, N'tran' FROM master..sysdatabases      
                WHERE (category & @transpublishdb_bit) <> 0 
        UNION
            select name, N'merge' from master..sysdatabases      
                WHERE (category & @mergepublishdb_bit) <> 0 
    FOR READ ONLY

    OPEN hCdropsubscriber
    FETCH hCdropsubscriber INTO @db_name, @type
    
    WHILE (@@fetch_status <> -1)
    BEGIN
        -- Bug 20323; used by UI
        IF LOWER(@reserved) = 'drop_subscriptions'
        BEGIN
            if @type = 'tran'
            begin
                SELECT @command = @db_name + '.dbo.sp_dropsubscription'
                EXECUTE @retcode  = @command 
                    @publication = 'all', 
                    @article = 'all', 
                    @subscriber = @subscriber,
                    @ignore_distributor = @ignore_distributor
            end
            if @type = 'merge'
            begin
                SELECT @command = @db_name + '.dbo.sp_dropmergesubscription'
                EXECUTE @retcode  = @command 
                    @publication = 'all', 
                    @subscriber = @subscriber,
                    @subscription_type = 'both',
                    @ignore_distributor = @ignore_distributor
            end
            IF @@ERROR <> 0 OR @retcode <> 0
            BEGIN
                CLOSE hCdropsubscriber
                DEALLOCATE hCdropsubscriber
                RETURN (1)
            END
        END
        

        if @type = 'tran'
        begin
            SELECT @command = @db_name + '.dbo.sp_helpsubscription'
            EXECUTE @retcode  = @command @publication = '%', @article = '%', 
                @subscriber = @subscriber,
                @found = @foundSubscription  OUTPUT

            IF @@ERROR <> 0 OR @retcode <> 0
            BEGIN
                CLOSE hCdropsubscriber
                DEALLOCATE hCdropsubscriber
                RETURN (1)
            END
        end
        else
        begin
            SELECT @command = @db_name + '.dbo.sp_helpmergesubscription'
            EXECUTE @retcode  = @command @publication = '%', 
                @subscriber = @subscriber,
                @subscription_type = 'both',
                @found = @foundSubscription  OUTPUT

            IF @@ERROR <> 0 OR @retcode <> 0
            BEGIN
                CLOSE hCdropsubscriber
                DEALLOCATE hCdropsubscriber
                RETURN (1)
            END
        end


        IF @foundSubscription <> 0
        BEGIN
            CLOSE hCdropsubscriber
            DEALLOCATE hCdropsubscriber
            RAISERROR ( 14144,  16, -1, @subscriber, @db_name)
            RETURN (1)
        END

        FETCH hCdropsubscriber INTO @db_name, @type
    END
    
    CLOSE hCdropsubscriber
    DEALLOCATE hCdropsubscriber

    /*
    ** Drop the subsubscriber_info in the distribution database
    */
    /*
    ** if @ignore_distributor = 1, we are in bruteforce cleanup mode, don't do RPC.
    */
    if @ignore_distributor = 0
    begin


        /*
        ** Get distribution server information for remote RPC
        ** agent verification.
        */
        EXEC @retcode = dbo.sp_helpdistributor 
            @rpcsrvname = @distributor OUTPUT,
            @distribdb = @distribdb OUTPUT
        IF @@error <> 0 OR @retcode <> 0
            BEGIN
            RAISERROR (14071, 16, -1)
               RETURN (1)
        END
        
        /*
        ** Insert information into MSsubscriber_info in the distribution db
        */
        if @distribdb is not null
        begin
            SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSdrop_subscriber_info'
            EXEC @retcode = @distproc
                 @publisher = @@SERVERNAME,
                 @subscriber = @subscriber

            IF @@error <> 0 OR @retcode <> 0
                BEGIN
                RAISERROR (14042, 16, -1)
                RETURN (1)
            END
        end
    end

    /*
    ** Turn off the subscriber server option.
    */
    EXECUTE @retcode = dbo.sp_serveroption @subscriber, 'sub', false
    IF @@ERROR <> 0 OR @retcode <> 0
    BEGIN
       RAISERROR (14047, 16, -1, @subscriber)
       RETURN (1)
    END

    RAISERROR (14062, 10, -1)
go
 
raiserror('Creating procedure sp_dsninfo', 0,1)
GO

CREATE PROCEDURE sp_dsninfo
--  xp_dsninfo does not support unicode
    @dsn varchar(128),
    @infotype varchar(128) = NULL,
    @login varchar(128) = NULL,
    @password varchar(128) = NULL,
    @dso_type int = 1  /* 1 is ODBC, 3 OLEDB. */
    AS

    SET NOCOUNT ON

    DECLARE @distributor sysname
    DECLARE @distproc nvarchar (255)
    DECLARE @retcode int
    DECLARE @dsotype_odbc int
    DECLARE @dsotype_oledb int

    select @dsotype_odbc = 1
    select @dsotype_oledb = 3

    /*
    ** Get distribution server information for remote RPC
    ** subscription calls.
    */

    EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT
    IF @@error <> 0 OR @retcode <> 0
        BEGIN
        RAISERROR (14071, 16, -1)
            RETURN (1)
    END

    if (@dso_type = @dsotype_odbc)
    begin
        /*
        ** Call xp_dsninfo
        */
        SELECT @distproc = RTRIM(@distributor) + '.master..xp_dsninfo'
        EXEC @retcode = @distproc @dsn, @infotype, @login, @password
        IF @@error <> 0
            BEGIN
            RAISERROR (14071, 16, -1)
            RETURN (1)
        END
    end
    else if (@dso_type = @dsotype_oledb)
    begin
        /*
        ** Call sp_oledbinfo
        */
        EXEC @retcode = master.dbo.sp_oledbinfo @dsn, @infotype, @login, @password
        IF @@error <> 0
            BEGIN
            RAISERROR (14071, 16, -1)
            RETURN (1)
        END
    end

go
 
dump tran master with no_log
go

raiserror('Creating procedure sp_publishdb', 0,1)
GO

/* For backward compatible */
CREATE PROCEDURE sp_publishdb @dbname sysname,@value nvarchar (5)
    AS

    DECLARE @retcode int

    EXECUTE @retcode = dbo.sp_replicationdboption @dbname, 'publish', @value

    IF @@ERROR <> 0 or @retcode <> 0
    BEGIN
       RETURN (1)
    END

    RETURN(0)
go
 

raiserror('Creating procedure sp_MScreate_dist_tables', 0,1)
GO

CREATE PROCEDURE sp_MScreate_dist_tables
AS

   /*
   ** Important:  
   ** We use varbinary(16) for xact_id and xact_seqno, we don't want ending nulls
   ** to be truncated by the server
   **
   ** Also, in MSrepl_commands, we don't want ending space to be truncated.  
   */
   SET ANSI_PADDING ON

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSrepl_version' and type = 'U')
   BEGIN
      /****************************************************************************/
      raiserror('Creating table MSrepl_version', 0,1)
      /****************************************************************************/
      CREATE TABLE dbo.MSrepl_version
      (
      major_version int NOT NULL,
      minor_version int NOT NULL,
      revision int NOT NULL,
      db_existed bit NULL
      )
    
      EXEC dbo.sp_MS_marksystemobject 'MSrepl_version'
      
      INSERT INTO MSrepl_version VALUES (7,0,0,0)
   END

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSpublisher_databases' and type = 'U')
   BEGIN
      /****************************************************************************/
      raiserror('Creating table MSpublisher_databases', 0,1)
      /****************************************************************************/
      CREATE TABLE dbo.MSpublisher_databases(
        publisher_id smallint NOT NULL,
        publisher_db sysname NULL,
        id int identity NOT NULL,                   
    )
      EXEC dbo.sp_MS_marksystemobject 'MSpublisher_databases'

      raiserror('Creating clustered index ucMSpublisher_databases', 0,1)
      CREATE UNIQUE CLUSTERED INDEX ucMSpublisher_databases ON dbo.MSpublisher_databases
     (publisher_id, publisher_db, id)
   END

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSpublications' and type = 'U')
   BEGIN
      /****************************************************************************/
      raiserror('Creating table MSpublications', 0,1)
      /****************************************************************************/
      CREATE TABLE dbo.MSpublications (
        publisher_id smallint NOT NULL,
        publisher_db sysname NULL,
        publication sysname NOT NULL,
        publication_id int identity NOT NULL,   -- This id IS NOT the same as the SQL Server publisher's
        publication_type int NOT NULL,          -- 0 = Snapshot 1 = Transactional
        thirdparty_flag bit NOT NULL,           -- 0 = SQL Server 1 = Third Party
        independent_agent bit NOT NULL,
        immediate_sync bit NOT NULL,
        allow_push bit NOT NULL,
        allow_pull bit NOT NULL,
        allow_anonymous bit NOT NULL,
        description nvarchar(255) NULL,
        vendor_name nvarchar(100) NULL,
        retention	int NULL
    )
      EXEC dbo.sp_MS_marksystemobject 'MSpublications'

	 -- publication_id needs to be the first columns in the index. It
	 -- is used in sp_MSmaximum_cleanup_seqno.
      raiserror('Creating clustered index ucMSpublications', 0,1)
      CREATE UNIQUE CLUSTERED INDEX ucMSpublications ON dbo.MSpublications
     (publication_id,  publication, publisher_db, publisher_id)

   END

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSarticles' and type = 'U')
   BEGIN
      /****************************************************************************/
      raiserror('Creating table MSarticles', 0,1)
      /****************************************************************************/
    CREATE TABLE dbo.MSarticles (
        publisher_id smallint NOT NULL,
        publisher_db sysname NULL,
        publication_id int NOT NULL,
        article sysname NOT NULL,
        article_id int NOT NULL,                            -- This id is the same as a SQL Server Publisher's
        destination_object sysname NULL,
        source_owner    sysname NULL,
        source_object sysname NULL,
        description nvarchar(255) NULL  
    )   

      EXEC dbo.sp_MS_marksystemobject 'MSarticles'

      raiserror('Creating clustered index ucMSarticles', 0,1)
      CREATE UNIQUE CLUSTERED INDEX ucMSarticles ON dbo.MSarticles
     (publisher_db, publisher_id, article_id, article, publication_id)
   END

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSsubscriptions' and type = 'U')
   BEGIN
      /****************************************************************************/
      raiserror('Creating table MSsubscriptions', 0,1)
      /****************************************************************************/
       CREATE TABLE dbo.MSsubscriptions
      (
        publisher_database_id int NOT NULL,         -- Used to reference MSrepl_transactions and MSrepl_commands
        publisher_id smallint NOT NULL,
        publisher_db sysname NOT NULL,
        publication_id int NOT NULL,
        article_id int NOT NULL,
        subscriber_id smallint NOT NULL,
        subscriber_db sysname NOT NULL,
        subscription_type int NOT NULL,         -- 0 = push, 1 = pull, 2 = anonymous 
        sync_type tinyint NOT NULL,                 -- 1 = automatic 2 = no sync
        status tinyint NOT NULL,                        -- 0 = inactive, 1 = subscribed, 2 = active 
        subscription_seqno varbinary(16) NOT NULL,  -- publisher's database sequence number 
        snapshot_seqno_flag bit NOT NULL,               -- 1 if subscription_seqno is the snapshot seqno
        independent_agent bit NOT NULL,             -- Value carried over from MSpublications
        subscription_time datetime NOT NULL, 
        loopback_detection bit NOT NULL,  
        agent_id int NOT NULL,
        update_mode tinyint NOT NULL,
        publisher_seqno varbinary(16) NOT NULL
      )

      EXEC dbo.sp_MS_marksystemobject 'MSsubscriptions'

      raiserror('Creating clustered index ucMSsubscirptions', 0,1)
      CREATE UNIQUE CLUSTERED INDEX ucMSsubscriptions ON dbo.MSsubscriptions
      (agent_id, article_id)

	  -- Index used by sp_MSdelete_publisherdb_trans
      raiserror('Creating index iMSsubscriptions', 0,1)
      CREATE INDEX iMSsubscriptions ON dbo.MSsubscriptions
      (publisher_database_id, article_id, subscriber_id, subscriber_db, publication_id, publisher_db, publisher_id)
   END
   
   -- For beta 3 upgrade, we need to create new index here.
   if not exists (select * from sysindexes where name = 'iMSsubscriptions2')
   begin
	  -- Index used by sp_MSdelete_publisherdb_trans
      raiserror('Creating index iMSsubscriptions2', 0,1)
      CREATE INDEX iMSsubscriptions2 ON dbo.MSsubscriptions
      (publisher_database_id, subscription_seqno)
   end

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSmerge_subscriptions' and type = 'U')
   BEGIN
      /****************************************************************************/
      raiserror('Creating table MSmerge_subscriptions', 0,1)
      /****************************************************************************/
       CREATE TABLE dbo.MSmerge_subscriptions
      (
        publisher_id smallint NOT NULL,
        publisher_db sysname NULL,
        publication_id int NOT NULL,
        subscriber_id smallint NOT NULL,
        subscriber_db sysname NULL,
        subscription_type int NULL,         -- 0 = push, 1 = pull, 2 = anonymous 
        sync_type tinyint NOT NULL,                 -- 1 = automatic 2 = no sync
        status tinyint NOT NULL,                        -- 0 = inactive, 1 = subscribed, 2 = active 
        subscription_time datetime NOT NULL
      )

      EXEC dbo.sp_MS_marksystemobject 'MSmerge_subscriptions'

      raiserror('Creating clustered index ucMSmerge_subscriptions', 0,1)
      CREATE UNIQUE CLUSTERED INDEX ucMSmerge_subscriptions ON dbo.MSmerge_subscriptions
     (publisher_id, publisher_db, publication_id, subscriber_id, subscriber_db)
   END


   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSrepl_transactions' and type = 'U')
   BEGIN
      /****************************************************************************/
      raiserror('Creating table MSrepl_transactions', 0,1)
      /****************************************************************************/
      CREATE TABLE dbo.MSrepl_transactions
      (
      publisher_database_id int NOT NULL,
      xact_id varbinary(16) NULL,
      xact_seqno varbinary (16 )  NOT NULL,
      entry_time datetime  NOT NULL
      )

      EXEC dbo.sp_MS_marksystemobject 'MSrepl_transactions'

      raiserror('Creating clustered index usMSrepl_transactions', 0,1)
      CREATE UNIQUE CLUSTERED INDEX ucMSrepl_transactions ON dbo.MSrepl_transactions
         (publisher_database_id, xact_seqno)
   END

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSrepl_commands' and type = 'U')
   BEGIN

      /****************************************************************************/
      raiserror('Creating table MSrepl_commands', 0,1)
      /****************************************************************************/


      CREATE TABLE dbo.MSrepl_commands (
      publisher_database_id int not null,
      xact_seqno varbinary(16) not null,
      type int not null, 
      article_id int not null,
      originator_id int not null,
      command_id int not null,
      partial_command bit not null,
      command varbinary(1024) NULL
      )

      EXEC dbo.sp_MS_marksystemobject 'MSrepl_commands'

      raiserror('Creating clusterd index ucMSrepl_commands', 0,1)
      CREATE UNIQUE CLUSTERED INDEX ucMSrepl_commands ON dbo.MSrepl_commands
         (publisher_database_id, xact_seqno, command_id)
   END


   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSrepl_originators' and type = 'U')
   BEGIN
      /****************************************************************************/
      raiserror('Creating table MSrepl_orginators', 0,1)
      /****************************************************************************/
      CREATE TABLE dbo.MSrepl_originators
      (
      id int identity not null,
      publisher_database_id int not null,
      srvname   sysname not null,
      dbname    sysname not null
      )

      EXEC dbo.sp_MS_marksystemobject 'MSrepl_originators'

      raiserror('Creating clustered index usMSrepl_originators', 0,1)
      CREATE UNIQUE CLUSTERED INDEX ucMSrepl_originators ON dbo.MSrepl_originators
         (publisher_database_id, srvname, dbname)
   END

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSsubscriber_info' and type = 'U')
   BEGIN
      /****************************************************************************/
      raiserror('Creating table MSsubscriber_info', 0,1)
      /****************************************************************************/
      CREATE TABLE dbo.MSsubscriber_info
      (
      publisher  sysname NOT NULL,
      subscriber  sysname NOT NULL,
      type tinyint NOT NULL,           /* 0: MS SQL Server 1: ODBC Data Source */
      login sysname NULL,
      password sysname NULL,
      description nvarchar(255) NULL,
      security_mode int NOT NULL
      )

      EXEC dbo.sp_MS_marksystemobject 'MSsubscriber_info'

      raiserror('Creating clustered index ucMSsubscriber_info', 0,1)
      CREATE UNIQUE CLUSTERED INDEX ucMSsubscriber_info ON dbo.MSsubscriber_info
     (publisher, subscriber)
   END
   ELSE
   BEGIN
      IF NOT EXISTS (select * from syscolumns
        where name = 'description'
        and id=object_id('MSsubscriber_info'))
      BEGIN
         
         ALTER TABLE MSsubscriber_info ADD description nvarchar (255) NULL
         UPDATE MSsubscriber_info SET description = 'SQL Server 6.0'
      END
   END

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSsubscriber_schedule' and type = 'U')
   BEGIN
         raiserror('Creating table MSsubscriber_schedule', 0,1)
         
        CREATE TABLE dbo.MSsubscriber_schedule
        (
            publisher  sysname NOT NULL,
            subscriber  sysname NOT NULL,
            agent_type      smallint NOT NULL,   -- 0 for distribution agent, 1 for merge agent
            frequency_type int NOT NULL,
            frequency_interval int NOT NULL,
            frequency_relative_interval int NOT NULL,
            frequency_recurrence_factor int NOT NULL,
            frequency_subday int NOT NULL,
            frequency_subday_interval int NOT NULL,
            active_start_time_of_day int NOT NULL,
            active_end_time_of_day int NOT NULL,
            active_start_date int NOT NULL,
            active_end_date int NOT NULL
        )
      EXEC dbo.sp_MS_marksystemobject 'MSsubscriber_schedule'

        CREATE UNIQUE CLUSTERED INDEX ucMSsubscriber_schedule ON dbo.MSsubscriber_schedule
     (publisher, subscriber, agent_type)
     
    END

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSsnapshot_history' and type = 'U')
   BEGIN
        /****************************************************************************/
         raiserror('Creating table MSsnapshot_history', 0,1)
        /****************************************************************************/
        CREATE TABLE dbo.MSsnapshot_history 
        (
        agent_id int NOT NULL,
        runstatus int NOT NULL,
        start_time datetime NOT NULL,        
        time datetime NOT NULL,    
        duration int NOT NULL,            
        comments nvarchar(255) NOT NULL,

        -- Session summary statistics
        delivered_transactions int NOT NULL,
        delivered_commands int NOT NULL,
        delivery_rate float NOT NULL,

        error_id int NOT NULL,
        timestamp NOT NULL
    )

      EXEC dbo.sp_MS_marksystemobject 'MSsnapshot_history'

     raiserror('Creating clustered index ucMSsnapshot_history', 0,1)
    CREATE CLUSTERED INDEX ucMSsnapshot_history ON dbo.MSsnapshot_history
        (agent_id, timestamp, start_time, time)

   END
       
   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSlogreader_history' and type = 'U')
   BEGIN
        /****************************************************************************/
        raiserror('Creating table MSlogreader_history', 0,1)
        /****************************************************************************/    
        CREATE TABLE dbo.MSlogreader_history
        (
        agent_id int NOT NULL,
        runstatus int NOT NULL,
        start_time datetime NOT NULL,
        time datetime NOT NULL,
        duration int NOT NULL,
        comments nvarchar(255) NOT NULL,
        xact_seqno varbinary(16) NULL,

        -- Session summary statistics
        delivery_time int NOT NULL,
        delivered_transactions int NOT NULL,
        delivered_commands int NOT NULL,
        average_commands int NOT NULL,
        delivery_rate float NOT NULL,
        delivery_latency int NOT NULL,

        error_id int NOT NULL,
        timestamp NOT NULL
        )

      EXEC dbo.sp_MS_marksystemobject 'MSlogreader_history'

    raiserror('Creating clustered index ucMSlogreader_history', 0,1)
    CREATE CLUSTERED INDEX ucMSlogreader_history ON dbo.MSlogreader_history
        (agent_id, timestamp, runstatus, start_time, time) 
   END

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSdistribution_history' and type = 'U')
   BEGIN
        /****************************************************************************/
          raiserror('Creating table MSdistribution_history', 0,1)
        /****************************************************************************/    

        CREATE TABLE dbo.MSdistribution_history
        (
        agent_id int NOT NULL,
        runstatus int NOT NULL,
        start_time datetime NOT NULL,
        time datetime NOT NULL,
        duration int NOT NULL,
        comments nvarchar(255) NOT NULL,
        xact_seqno varbinary(16) NULL,

        -- Current statistics
        current_delivery_rate float NOT NULL,
        current_delivery_latency int NOT NULL,

        -- Session summary statistics
        delivered_transactions int NOT NULL,
        delivered_commands int NOT NULL,
        average_commands int NOT NULL,
        delivery_rate float NOT NULL,       
        delivery_latency int NOT NULL, 

        -- Summary statistics across all sessions
        total_delivered_commands int NOT NULL, 

        error_id int NOT NULL,
        updateable_row bit NOT NULL,
        timestamp NOT NULL
        )

    EXEC dbo.sp_MS_marksystemobject 'MSdistribution_history'

    raiserror('Creating clustered index ucMSdistribution_history', 0,1)
    CREATE CLUSTERED INDEX ucMSdistribution_history ON dbo.MSdistribution_history
        (agent_id, timestamp, runstatus, start_time, time) 
   END

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSmerge_history' and type = 'U')
   BEGIN
        /****************************************************************************/
      raiserror('Creating table MSmerge_history', 0,1)
        /****************************************************************************/    

        CREATE TABLE dbo.MSmerge_history
        (
        agent_id                    int             NOT NULL,
        runstatus               int             NOT NULL,
        start_time              datetime        NOT NULL,
        time                    datetime        NOT NULL,
        duration                int             NOT NULL,
        comments                nvarchar(255)   NOT NULL,
        delivery_time               int         NOT NULL,
        delivery_rate               float       NOT NULL,
        publisher_insertcount       int         NULL,
        publisher_updatecount       int         NULL,
        publisher_deletecount       int         NULL,
        publisher_conflictcount     int         NULL,
        subscriber_insertcount      int         NULL,
        subscriber_updatecount      int         NULL,
        subscriber_deletecount      int         NULL,
        subscriber_conflictcount    int         NULL,
        error_id                    int         NOT NULL,
        timestamp                               NOT NULL,
		updateable_row				bit			NOT NULL
        )        

    EXEC dbo.sp_MS_marksystemobject 'MSmerge_history'

    raiserror('Creating clustered index ucMSmerge_history', 0,1)
    CREATE CLUSTERED INDEX ucMSmerge_history ON dbo.MSmerge_history
        (agent_id, timestamp, runstatus, start_time, time) 
   END
   ELSE
   BEGIN
      IF NOT EXISTS (select * from syscolumns
        where name = 'updateable_row'
        and id=object_id('MSmerge_history'))
      BEGIN
         
         ALTER TABLE MSmerge_history ADD updateable_row bit default 1 NOT NULL
      END
   END


   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSrepl_errors' and type = 'U')
   BEGIN
        /****************************************************************************/
        raiserror('Creating table MSrepl_errors', 0,1)
        /****************************************************************************/    

        CREATE TABLE dbo.MSrepl_errors
        (
        id                  int NOT NULL,
        time                datetime NOT NULL,
        error_type_id       int NULL,
        source_type_id      int NULL,
        source_name         nvarchar(100) NULL,
        error_code          sysname NULL,
        error_text          ntext NULL
        )

      EXEC dbo.sp_MS_marksystemobject 'MSrepl_errors'

    raiserror('Creating clustered index ucMSrepl_errors', 0,1)
    CREATE CLUSTERED INDEX ucMSrepl_errors ON dbo.MSrepl_errors
        (id, time) -- WITH ALLOW_DUP_ROW
   END

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSsnapshot_agents' and type = 'U')
   BEGIN
        /****************************************************************************/
        raiserror('Creating table MSsnapshot_agents', 0,1)
        /****************************************************************************/    

        CREATE TABLE dbo.MSsnapshot_agents
        (
        id                  int IDENTITY NOT NULL,
        name                nvarchar(100) NOT NULL,
        publisher_id        smallint NOT NULL,
        publisher_db        sysname NOT NULL,
        publication         sysname NOT NULL,
        publication_type    int NOT NULL,       -- 0 transactional 1 snapshot 2 merge
        local_job           bit NOT NULL,
        job_id              binary(16) NULL,
        profile_id  int     NOT NULL
        )

      EXEC dbo.sp_MS_marksystemobject 'MSsnapshot_agents'

    raiserror('Creating clustered index ucMSsnapshot_agents', 0,1)
    CREATE CLUSTERED INDEX ucMSsnapshot_agents ON dbo.MSsnapshot_agents
        (publication, publisher_db, publisher_id) 

    raiserror('Creatingindex iMSsnapshot_agents', 0,1)
    CREATE INDEX iMSsnapshot_agents ON dbo.MSsnapshot_agents
        (id)
   END

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSlogreader_agents' and type = 'U')
   BEGIN
        /****************************************************************************/
        raiserror('Creating table MSlogreader_agents', 0,1)
        /****************************************************************************/    

        CREATE TABLE dbo.MSlogreader_agents
        (
        id                  int IDENTITY NOT NULL,
        name                nvarchar(100) NOT NULL,
        publisher_id        smallint NOT NULL,
        publisher_db        sysname NOT NULL,
        publication         sysname NOT NULL,-- Not used for SQL Server publisher
        local_job           bit NOT NULL,
        job_id              binary(16) NULL,
        profile_id  int     NOT NULL
        )

      EXEC dbo.sp_MS_marksystemobject 'MSlogreader_agents'

    raiserror('Creating clustered index ucMSlogreader_agents', 0,1)
    CREATE CLUSTERED INDEX ucMSlogreader_agents ON dbo.MSlogreader_agents
        (publisher_db, publisher_id) 

    raiserror('Creatingindex iMSlogreader_agents', 0,1)
    CREATE INDEX iMSlogreader_agents ON dbo.MSlogreader_agents
        (id)
   END

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSdistribution_agents' and type = 'U')
   BEGIN
        /****************************************************************************/
        raiserror('Creating table MSdistribution_agents', 0,1)
        /****************************************************************************/    

        CREATE TABLE dbo.MSdistribution_agents
        (
		id                  int IDENTITY NOT NULL,
		name                nvarchar(100) NOT NULL,
		publisher_database_id int NOT NULL,
		publisher_id        smallint NOT NULL,
		publisher_db        sysname NOT NULL,
		publication         sysname NOT NULL,
		subscriber_id       smallint NULL, 
		subscriber_db       sysname NULL,
		subscription_type   int NOT NULL,
		local_job           bit NULL,
		job_id              binary(16) NULL,
		subscription_guid   binary(16) NOT NULL,
		profile_id  int     NOT NULL,
		anonymous_subid     uniqueidentifier NULL,
		subscriber_name     sysname NULL,
		virtual_agent_id    int NULL,
		anonymous_agent_id  int NULL,
		creation_date		datetime default (getdate()) not NULL
        )

        EXEC dbo.sp_MS_marksystemobject 'MSdistribution_agents'

        raiserror('Creating clustered index ucMSdistribution_agents', 0,1)
        CREATE CLUSTERED INDEX ucMSdistribution_agents ON dbo.MSdistribution_agents
            (id)

        raiserror('Creatingindex iMSdistribution_agents', 0,1)
        CREATE INDEX iMSdistribution_agents ON dbo.MSdistribution_agents
            (publication, publisher_db, publisher_id, subscriber_id, subscriber_db, anonymous_subid) 
   END

	if not exists (select * from syscolumns where 
		id = object_id('MSdistribution_agents') and
		name = 'creation_date')
	begin
		alter table MSdistribution_agents add creation_date datetime default (getdate()) not null
	end 

   IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSmerge_agents' and type = 'U')
   BEGIN
        /****************************************************************************/
        raiserror('Creating table MSmerge_agents', 0,1)
        /****************************************************************************/    

        CREATE TABLE dbo.MSmerge_agents
        (
		id                  int IDENTITY NOT NULL,
		name                nvarchar(100) NOT NULL,
		publisher_id        smallint NOT NULL,
		publisher_db        sysname NOT NULL,
		publication         sysname NOT NULL,
		subscriber_id       smallint NULL,
		subscriber_db       sysname NULL,
		local_job           bit NULL,
		job_id              binary(16) NULL,
		profile_id          int NULL,
		anonymous_subid     uniqueidentifier NULL,
		subscriber_name     sysname NULL,
		creation_date		datetime default (getdate()) not NULL
        )

      EXEC dbo.sp_MS_marksystemobject 'MSmerge_agents'

    raiserror('Creating clustered index ucMSmerge_agents', 0,1)
    CREATE CLUSTERED INDEX ucMSmerge_agents ON dbo.MSmerge_agents
        (publication, publisher_db, publisher_id, subscriber_id, subscriber_db, anonymous_subid) 
    
    raiserror('Creatingindex iMSmerge_agents', 0,1)
    CREATE INDEX iMSmerge_agents ON dbo.MSmerge_agents
        (id)
	END

	if not exists (select * from syscolumns where 
		id = object_id('MSmerge_agents') and
		name = 'creation_date')
	begin
		alter table MSmerge_agents add creation_date datetime default (getdate()) not null
	end 

	IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSpublication_access' and type = 'U')
	BEGIN
		/****************************************************************************/
		raiserror('Creating table MSpublication_access', 0,1)
		/****************************************************************************/    

		CREATE TABLE dbo.MSpublication_access
		(
		publication_id      int NULL,       -- Publication_id is unique in distribution database.
		login               sysname NOT NULL
											-- Logins in the publication access list, they nust
											-- exist at both publisher and distributor side.            
		)

		EXEC dbo.sp_MS_marksystemobject 'MSpublication_access'

		raiserror('Creating clustered index ucMSpublication_access', 0,1)
		CREATE CLUSTERED INDEX ucMSpublication_access ON dbo.MSpublication_access
			(publication_id, login) 
	END

	-- For b3 upgrade
	if NOT EXISTS (select * from syscolumns where name='retention' and id=object_id('MSpublications'))
	begin
		alter table MSpublications add retention int NULL 
		UPDATE msdb..MSdistributiondbs set max_distretention=72 where
			name = db_name()
	end

	-- drop default_access column
	if exists (select * from syscolumns where id = object_id('MSpublications') and
		name = 'default_access')
	begin
		alter table MSpublications drop column default_access
	end 

	-- Drop publisher_id column
	if EXISTS (select * from syscolumns where name='publisher_id' and id=object_id('MSpublication_access'))
	begin
		drop index MSpublication_access.ucMSpublication_access

		alter table MSpublication_access drop column publisher_id

		raiserror('Creating clustered index ucMSpublication_access', 0,1)
		CREATE CLUSTERED INDEX ucMSpublication_access ON dbo.MSpublication_access
		(publication_id, login) 
	end


GO

dump tran master with no_log
go

raiserror('Creating procedure sp_MSadd_distributor_alerts_and_responses', 0,1)
go
create proc sp_MSadd_distributor_alerts_and_responses
as

    declare @description    nvarchar(500)
    declare @category_name  sysname
    declare @agent_name     sysname
    declare @response_job   nvarchar(100)
    declare @alert_name     nvarchar(100)
    declare @alert_id       int
    declare @retcode        int

    --
    -- Add replication alert response jobs
    --
    select @category_name = name FROM msdb.dbo.syscategories where category_id = 18

    -- Add Validation failure response job
    -- (20570,10,0,'Reinitialize Subscriptions On Validation Failure.', 1033)   -- Title of a alert response job
    -- (20571,10,0,'Reiniitializes all subscriptions that have failed due to data validation failures.', 1033)  -- Description of a alert response job
    set @response_job = formatmessage(20570)
    set @description = formatmessage(20571)
    
    -- Delete the job if it already exists
    if (exists (select * from msdb..sysjobs_view where name = @response_job))
    begin
        exec @retcode = msdb.dbo.sp_delete_job @job_name = @response_job
        if @@ERROR <> 0 or @retcode <> 0
            return (1)
    end

    execute @retcode = msdb.dbo.sp_MSadd_repl_job 
        @response_job,
        @subsystem = 'TSQL',
        @server = @@SERVERNAME,
        @databasename = 'master',
        @description = @description,
        @command = 'exec dbo.sp_MSreinit_failed_subscriptions @failure_level = 1',
        @enabled = 1,
        @loghistcompletionlevel = 0,
        @retryattempts = 0,
        @category_name = @category_name
    if @@ERROR <> 0 or @retcode <> 0
        return (1)

    --
    -- Add replication alerts
    --

    -- Get Replication category name (assumes category_id = 20)
    select @category_name = name FROM msdb.dbo.syscategories where category_id = 20

    -- Add Failure Alert
    set @alert_name = formatmessage(20536)  
    set @alert_id = 14151 -- corresponding to formatmessage(20536),  Failure alert
    if not exists (select * from msdb.dbo.sysalerts where message_id = @alert_id)
    begin
        exec @retcode = msdb.dbo.sp_add_alert @enabled = 0, @name = @alert_name, @category_name = @category_name, @message_id = 14151
        if @@error <> 0 or @retcode <> 0
            return 1
    end

    -- Add Retry Alert
    set @alert_name=formatmessage(20537)
    set @alert_id = 14152 -- corresponding to formatmessage(20537),  Retry alert
    if not exists (select * from msdb.dbo.sysalerts where message_id = @alert_id)
    begin
        exec @retcode = msdb.dbo.sp_add_alert @enabled = 0, @name = @alert_name, @category_name = @category_name, @message_id = 14152
        if @@error <> 0 or @retcode <> 0
            return 1
    end

    -- Add Success Alert
    set @alert_name=formatmessage(20540)
    set @alert_id = 14150 -- corresponding to formatmessage(20540), 
    if not exists (select * from msdb.dbo.sysalerts where message_id = @alert_id)
    begin
        exec @retcode = msdb.dbo.sp_add_alert @enabled = 0, @name = @alert_name, @category_name = @category_name, @message_id = 14150
        if @@error <> 0 or @retcode <> 0
            return 1
    end

    -- Add Shutdown request Alert
    set @alert_name=formatmessage(20578)
    set @alert_id = 20578 --  Custom agent shutdown message
    if not exists (select * from msdb.dbo.sysalerts where message_id = @alert_id)
    begin
        exec @retcode = msdb.dbo.sp_add_alert @enabled = 0, @name = @alert_name, @category_name = @category_name, @message_id = 20578
        if @@error <> 0 or @retcode <> 0
            return 1
    end

    -- Add Validation Failure Alert
    set @alert_name=formatmessage(20565)
    set @alert_id = 20574 -- corresponding to formatmessage(20574), 
    if not exists (select * from msdb.dbo.sysalerts where message_id = @alert_id)
    begin
        exec @retcode = msdb.dbo.sp_add_alert @enabled = 0, @name = @alert_name, @category_name = @category_name, @message_id = 20574
        if @@error <> 0 or @retcode <> 0
            return 1
    end

    -- Add Validation Success Alert
    set @alert_name=formatmessage(20566)
    set @alert_id = 20575 -- corresponding to formatmessage(20575), 
    if not exists (select * from msdb.dbo.sysalerts where message_id = @alert_id)
    begin
        exec @retcode = msdb.dbo.sp_add_alert @enabled = 0, @name = @alert_name, @category_name = @category_name, @message_id = 20575
        if @@error <> 0 or @retcode <> 0
            return 1
    end

    -- Add Reinitialized after Validation Failure
    set @alert_name=formatmessage(20573)
    set @alert_id = 20572 -- corresponding to formatmessage(20566),  
    if not exists (select * from msdb.dbo.sysalerts where message_id = @alert_id)
    begin
        exec @retcode = msdb.dbo.sp_add_alert @enabled = 0, @name = @alert_name, @category_name = @category_name, @message_id = 20572
        if @@error <> 0 or @retcode <> 0
            return 1
    end

GO


raiserror('Creating procedure sp_MSdrop_distributor_alerts_and_responses', 0,1)
go
create proc sp_MSdrop_distributor_alerts_and_responses
as

    declare @name           nvarchar(100)
    declare @alert_id       int
    declare @retcode        int

    --
    -- Delete alerts and response jobs
    --

    -- Drop Replication Checkup Agent
    select @name = formatmessage(20533)
    IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @name and
        originating_server = '(local)')
    BEGIN
        EXEC @retcode = msdb.dbo.sp_delete_job  @job_name = @name
        IF @@ERROR <> 0 or @retcode <> 0
        BEGIN
            return (1)            
        END
    END

    -- Drop Reinit subscription response job
    set @name = formatmessage(20570)
    IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @name and
        originating_server = '(local)')
    BEGIN
        EXEC @retcode = msdb.dbo.sp_delete_job  @job_name = @name
        IF @@ERROR <> 0 or @retcode <> 0
        BEGIN
            return (1)            
        END
    END

    -- Drop the alerts
    set @alert_id = 14150 -- success alert
    set @name=formatmessage(20540)
    if exists (select * from msdb.dbo.sysalerts where message_id=@alert_id)
    begin
        select @name=name from msdb.dbo.sysalerts where message_id=@alert_id
        exec @retcode = msdb.dbo.sp_delete_alert @name
        if @@error <> 0 or @retcode <> 0
            return (1)            
    end
    
    set @alert_id = 14151 -- failure alert
    set @name = formatmessage(20536)
    if exists (select * from msdb.dbo.sysalerts where message_id=@alert_id)
    begin
        select @name=name from msdb.dbo.sysalerts where message_id=@alert_id
        exec @retcode = msdb.dbo.sp_delete_alert @name
        if @@error <> 0 or @retcode <> 0
            return (1)            
    end
    
    set @alert_id = 14152 -- retry alert
    set @name = formatmessage(20537)
    if exists (select * from msdb.dbo.sysalerts where message_id=@alert_id)
    begin
        select @name=name from msdb.dbo.sysalerts where message_id=@alert_id
        exec @retcode = msdb.dbo.sp_delete_alert @name
        if @@error <> 0 or @retcode <> 0
            return (1)            
    end

    set @alert_id = 14153 -- warnning alert
    set @name = formatmessage(20540)
    if exists (select * from msdb.dbo.sysalerts where message_id=@alert_id)
    begin
        select @name=name from msdb.dbo.sysalerts where message_id=@alert_id
        exec @retcode = msdb.dbo.sp_delete_alert @name
        if @@error <> 0 or @retcode <> 0
            return (1)            
    end

    -- Remove Validation Failure Alert
    set @alert_id = 20574 
    set @name = formatmessage(20565)
    if exists (select * from msdb.dbo.sysalerts where message_id=@alert_id)
    begin
        select @name=name from msdb.dbo.sysalerts where message_id=@alert_id
        exec @retcode = msdb.dbo.sp_delete_alert @name
        if @@error <> 0 or @retcode <> 0
            return (1)            
    end

    -- Remove Validation Sucess Alert
    set @alert_id = 20575
    set @name = formatmessage(20566)
    if exists (select * from msdb.dbo.sysalerts where message_id=@alert_id)
    begin
        select @name=name from msdb.dbo.sysalerts where message_id=@alert_id
        exec @retcode = msdb.dbo.sp_delete_alert @name
        if @@error <> 0 or @retcode <> 0
            return (1)            
    end
    
    -- Remove Reinitialized after Validation Failure
    set @alert_id = 20525 -- checksum alert
    set @name = formatmessage(20573)
    if exists (select * from msdb.dbo.sysalerts where message_id=@alert_id)
    begin
        select @name=name from msdb.dbo.sysalerts where message_id=@alert_id
        exec @retcode = msdb.dbo.sp_delete_alert @name
        if @@error <> 0 or @retcode <> 0
            return (1)            
    end

    -- Remove subscription reinitialized after validation failure
    set @alert_id = 20572 -- corresponding to formatmessage(20566),  
    set @name=formatmessage(20573)
    if exists (select * from msdb.dbo.sysalerts where message_id=@alert_id)
    begin
        select @name=name from msdb.dbo.sysalerts where message_id=@alert_id
        exec @retcode = msdb.dbo.sp_delete_alert @name
        if @@error <> 0 or @retcode <> 0
            return (1)            
    end

    -- Remove Shutdown request Alert
    set @alert_id = 20578 --  Custom agent shutdown message
    set @name=formatmessage(20578)
    if exists (select * from msdb.dbo.sysalerts where message_id=@alert_id)
    begin
        select @name=name from msdb.dbo.sysalerts where message_id=@alert_id
        exec @retcode = msdb.dbo.sp_delete_alert @name
        if @@error <> 0 or @retcode <> 0
            return (1)            
    end

GO
raiserror('Creating procedure sp_adddistributor', 0,1)
go

CREATE PROCEDURE sp_adddistributor (
    @distributor sysname,            /* distributor server name */
    @heartbeat_interval int = 10,    -- minutes
    @password sysname = NULL

) AS

    SET NOCOUNT ON

    /*
    ** Declarations.
    */
    DECLARE @retcode int
    DECLARE @agentname nvarchar(100)
    DECLARE @command nvarchar(255)
    DECLARE @distribution_db sysname
    DECLARE @distproc nvarchar(255)
    DECLARE @dist_rpcname sysname
    DECLARE @server_added bit
    declare @login sysname

    select @server_added = 0 
    select @login = 'distributor_admin'

    /* 
    ** Check if replication components are installed on this server
    */
    exec @retcode = dbo.sp_MS_replication_installed
    if (@retcode <> 1)
    begin
        return (1)
    end

    -- Must be at master db.
    IF db_name() <> 'master'
    BEGIN
        RAISERROR(5001, 16,-1)
        return (1)
    END
    /*
    ** Parameter Check:  @distributor.
    ** Check to make sure that the distributor is not NULL and that it
    ** conforms to the rules for identifiers.
    */
    IF @distributor IS NULL
        BEGIN
            RAISERROR (14043, 16, -1, '@distributor')
            RETURN (1)
        END

    EXECUTE @retcode = dbo.sp_validname @distributor

    IF @@ERROR <> 0 OR @retcode <> 0
       RETURN (1)

	IF @password = N''
		select @password = [REDACTED]
	
	-- Seed default password with random value.
	IF @password is null
		select @password = [REDACTED] newid())
    /*
    ** Check to make sure that the distributor doesn't already exist.
    */
    SELECT @dist_rpcname = NULL
    SELECT @dist_rpcname = srvname FROM master..sysservers
              WHERE  srvstatus & 8 <> 0
    IF @dist_rpcname IS NOT NULL
    BEGIN
        RAISERROR (14099, 16, -1, @dist_rpcname)
        RETURN(1)
    END

    -- drop repl_distributor if it exists.
    if exists (select * from master..sysservers where lower(srvname) = 
        'repl_distributor')
    begin
        exec @retcode = dbo.sp_dropserver 'repl_distributor', 'droplogins'
        IF @@error <> 0 OR @retcode <> 0
        BEGIN
            RETURN(1)
        END
    end

    -- Add the linked server entry for the distributor
    -- Note we do this even for local server for consistancy
    EXECUTE @retcode = dbo.sp_addserver  'repl_distributor'
    IF @@error <> 0 OR @retcode <> 0
    BEGIN
        RETURN (1)
    END

    select @server_added = 1

    -- Mark system link
    EXECUTE @retcode = dbo.sp_serveroption  'repl_distributor', 'system','true'
    IF @@error <> 0 OR @retcode <> 0
    BEGIN
        RETURN (1)
    END

    EXECUTE @retcode = dbo.sp_setnetname  'repl_distributor', @distributor
    IF @@error <> 0 OR @retcode <> 0
    BEGIN
        goto UNDO
    END
        
    exec @retcode = dbo.sp_addlinkedsrvlogin 
        @rmtsrvname= 'repl_distributor',
        @useself = 'false',
        @locallogin = NULL,
        @rmtuser = @login,
        @rmtpassword = [REDACTED]
    IF @@error <> 0 OR @retcode <> 0
    BEGIN
        goto UNDO
    END


    /*
    ** If this is not the local server, remote distributor must be set up first
    */
    IF UPPER(@distributor) <> UPPER(@@SERVERNAME)
    BEGIN
        /*
        ** Test to see if the local server is defined as publisher
        ** at the remove distributor.
        ** Note: cannot call sp_helpdistributor locally since the server is not
        ** marked for distribution.
        ** We can not move the serveroption call before this RPC because RPC failure
        ** may cause the SP to terminate. Thus, we can not UNDO the server option.
        ** give all parameters to work around SQL SERVER 7.0 rpc named param bug.
        */
        SELECT @distproc = 'repl_distributor.master.dbo.sp_helpdistributor'
    
        DECLARE @loc_directory             nvarchar(255)
        DECLARE @loc_account             nvarchar(255)
        DECLARE @loc_mindistretention     int
        DECLARE @loc_maxdistretention     int
        DECLARE @loc_historyretention   int  
        DECLARE @loc_historycleanupagent nvarchar(100)
        DECLARE @loc_distribcleanupagent nvarchar(100)
        DECLARE @alert_name nvarchar(100)
        DECLARE @alert_id int

        EXECUTE @distproc
            @distributor OUTPUT,
            @distribution_db OUTPUT,
            @loc_directory OUTPUT,
            @loc_account OUTPUT,
            @loc_mindistretention OUTPUT,
            @loc_maxdistretention OUTPUT,
            @loc_historyretention OUTPUT,
            @loc_historycleanupagent OUTPUT,
            @loc_distribcleanupagent OUTPUT,
            @@SERVERNAME,
            @local = 'local'

        IF @@error <> 0 OR @retcode <> 0 OR @distribution_db is NULL
        BEGIN
            RAISERROR (21007,16,-1)
            GOTO UNDO
        END

        /* Activate the dist publisher at the remote distributor */
        SELECT @distproc = 'repl_distributor.master.dbo.sp_changedistpublisher'
            EXECUTE @retcode = @distproc @@SERVERNAME, 'active','true'
        IF @@error <> 0 OR @retcode <> 0
        BEGIN
            GOTO UNDO
        END
    END
    ELSE
    /* set the registry */
    BEGIN
        EXEC @retcode = dbo.sp_MScreate_distributor_tables 
        if @@error <> 0 or @retcode <> 0
            goto UNDO

        declare @distributor_login sysname
        select @distributor_login = 'distributor_admin'

        -- Add publisher rpc login
        if not exists (select * from master..syslogins where loginname = @distributor_login)
        begin
            EXEC @retcode = dbo.sp_addlogin @loginame = @distributor_login,
				@passwd = [REDACTED]
            if @@error <> 0 or @retcode <> 0
                goto UNDO
        end
		else
		begin
			-- Change the password if the distributor is local
			EXEC @retcode = dbo.sp_password NULL, @password, 'distributor_admin'
			if @@error <> 0 or @retcode <> 0
				goto UNDO
		end

        -- Add the login to sysadmin
        -- Refer to sp_MSpublication_access in distribution db
        if is_srvrolemember('sysadmin', @distributor_login) <> 1
        begin
            exec @retcode = dbo.sp_addsrvrolemember @distributor_login, 'sysadmin'
            IF @@error <> 0 OR @retcode <> 0
                GOTO UNDO
        end

        -- Add Replication Agent Checkup Agent
        exec @retcode = dbo.sp_MScreate_replication_checkup_agent @heartbeat_interval = @heartbeat_interval
        if @@error <> 0 or @retcode <> 0
            goto UNDO
        
        delete msdb..MSdistributor where property = 'heartbeat_interval'
        if @@error <> 0
            goto UNDO
        insert into msdb..MSdistributor (property, value) values ('heartbeat_interval',
            convert(nvarchar(10), @heartbeat_interval))
        if @@error <> 0 
            goto UNDO

        -- Add Replication Alerts and Response Jobs
        exec @retcode = dbo.sp_MSadd_distributor_alerts_and_responses
        if @@error <> 0 or @retcode <> 0
            goto UNDO
    
    END


    /*
    ** Set the server option to indicate that this is a distributor.
    ** 
    */
    EXECUTE @retcode = dbo.sp_serveroption 'repl_distributor', 'dist', true
    IF @@error <> 0 OR @retcode <> 0
    BEGIN
        GOTO UNDO
    END

    -- Set sp_MSrepl_startup to be a startup stored procedure
    -- Note: This needs to be after the marking the distribution server
    exec @retcode = dbo.sp_procoption 'sp_MSrepl_startup', 'startup', 'true' 
    if @@error <> 0 or @retcode <> 0
        goto UNDO1

    exec @retcode = dbo.sp_MSrepl_startup
    if @@error <> 0 or @retcode <> 0
        goto UNDO1

    RETURN (0)

UNDO1:
    exec dbo.sp_serveroption 'repl_distributor', 'dist', false

UNDO:
    IF @server_added = 1
    begin
        -- Drop the remote logins, otherwise, sp_dropserver will fail.
        EXECUTE dbo.sp_dropserver 'repl_distributor', 'droplogins'
    end
    
    RETURN (1)
GO
 

raiserror('Creating procedure sp_changedistributor_property', 0,1)
go

CREATE PROCEDURE sp_changedistributor_property (
    @property sysname     = NULL,       /* The property to change */
    @value nvarchar(255)  = NULL        /* The new property value */
    ) AS

    declare @retcode int
    declare @new_heartbeat_interval int 

    -- Check to make sure the local server is a distributor
    if not exists (SELECT * FROM master..sysservers
              WHERE  srvstatus & 8 <> 0 and
              UPPER(datasource) = UPPER(@@servername))
    begin
        RAISERROR (14114, 16, -1, @@SERVERNAME)
        return(1)
    end

    -- Return list of properties if @property is NULL
    if @property is NULL
    begin
        create table #tab1 (properties sysname NOT NULL)
        insert into #tab1 values ('heartbeat_interval')
        select * from #tab1
        return (0)
    end

    if @property is NULL
    begin
        if exists (select name from msdb..sysobjects where name = 'MSdistributor')
        begin
            select property from msdb..MSdistributor
            return 0
        end
        return 1
    end

    -- Check for valid property
    IF LOWER(@property) NOT IN ('heartbeat_interval')
    BEGIN
        RAISERROR (14154, 16, -1)
        RETURN (1)
    END

    if LOWER(@property) = 'heartbeat_interval'
    begin
        if exists (select name from msdb..sysobjects where name = 'MSdistributor')  
        begin
            update msdb..MSdistributor set value = @value where property = @property
            if @@error <> 0
                return 1
            select @new_heartbeat_interval = CONVERT(int, @value)
            exec @retcode = dbo.sp_MScreate_replication_checkup_agent @heartbeat_interval = 
                @new_heartbeat_interval
            if @@error <> 0 or @retcode <> 0
                return 1
        end
        else 
            return 1
    end

    return (0)

GO

raiserror('Creating procedure sp_helpdistributor_properties', 0,1)
go

CREATE PROCEDURE sp_helpdistributor_properties 
     AS

    if exists (select name from msdb..sysobjects where name = 'MSdistributor')
    begin
        -- There is currently only one property, so this will work
        select 'heartbeat_interval' = convert(int, value) from msdb..MSdistributor where
            property = 'heartbeat_interval'
        return (0)
    end
    return (1)
GO

raiserror('Creating procedure sp_dropdistributor', 0,1)
go

CREATE PROCEDURE sp_dropdistributor
@no_checks bit = 0,
@ignore_distributor bit = 0
AS

    SET NOCOUNT ON

    /*
    ** Declarations.
    */
    DECLARE @retcode int
    DECLARE @distributor sysname
    DECLARE @agentname nvarchar(100)
    DECLARE @distbit int
    DECLARE @distribdb sysname
    DECLARE @foundSubscriber int
    DECLARE @proc nvarchar(255) 
    declare @optname sysname
    declare @name sysname
    DECLARE @transpublishdb_bit int
    DECLARE @mergepublishdb_bit int
    declare @job_name nvarchar(100)
    declare @alert_name nvarchar(100)

    declare @dist_rpcname sysname

    declare @alert_id   int
   
    SELECT @transpublishdb_bit = 1
    SELECT @mergepublishdb_bit = 4
    SELECT @foundSubscriber = 0
    SELECT @distbit = 16

    -- Get distributor name
    select @distributor = datasource, @dist_rpcname = srvname from master..sysservers 
        WHERE srvstatus & 8 <> 0
    if @distributor is null
    BEGIN
        RAISERROR (21043, 16, -1)
        RETURN(1)
    END

    if @no_checks = 1
    begin
        -- We are in bruteforce cleanup mode, drop everything.
        DECLARE hCdropdistributor CURSOR LOCAL FAST_FORWARD FOR
                SELECT name, N'publish' FROM master..sysdatabases      
                    WHERE (category & @transpublishdb_bit) <> 0 
                UNION
                select name, N'merge publish' from master..sysdatabases
                    WHERE (category & @mergepublishdb_bit) <> 0
                FOR READ ONLY

        OPEN hCdropdistributor
        FETCH hCdropdistributor INTO @name, @optname
    
        WHILE (@@fetch_status <> -1)
        BEGIN
                        
            EXECUTE @retcode  = dbo.sp_replicationdboption 
              @dbname = @name,
              @optname = @optname,
              @value = 'false',
              @ignore_distributor = @ignore_distributor
            
            IF @@ERROR <> 0 OR @retcode <> 0
            BEGIN
                CLOSE hCdropdistributor
                DEALLOCATE hCdropdistributor
                RETURN (1)
            END
            FETCH hCdropdistributor INTO @name, @optname
        end

        CLOSE hCdropdistributor
        DEALLOCATE hCdropdistributor
    
        -- Drop subscriber
        EXECUTE @retcode  = dbo.sp_dropsubscriber
          @subscriber = 'all',
          @ignore_distributor = @ignore_distributor

        IF @@ERROR <> 0 OR @retcode <> 0
            RETURN (1)

        IF UPPER(@distributor) = UPPER(@@SERVERNAME) 
        begin
            -- Clean up dist publishers
            DECLARE hCdropdistributor CURSOR LOCAL FAST_FORWARD FOR
                    SELECT name FROM msdb..MSdistpublishers
            FOR READ ONLY

            OPEN hCdropdistributor
            FETCH hCdropdistributor INTO @name

            WHILE (@@fetch_status <> -1)
            BEGIN
                exec @retcode = dbo.sp_dropdistpublisher
                    @publisher = @name,
                    @no_checks = 1
            
                IF @@ERROR <> 0 OR @retcode <> 0
                BEGIN
                    CLOSE hCdropdistributor
                    DEALLOCATE hCdropdistributor
                    RETURN (1)
                END
                FETCH hCdropdistributor INTO @name
            end

            CLOSE hCdropdistributor
            DEALLOCATE hCdropdistributor

            -- Clean up distribution dbs
            DECLARE hCdropdistributor CURSOR LOCAL FAST_FORWARD FOR
                    SELECT name FROM msdb..MSdistributiondbs
            FOR READ ONLY

            OPEN hCdropdistributor
            FETCH hCdropdistributor INTO @name
    
            WHILE (@@fetch_status <> -1)
            BEGIN
                exec @retcode = dbo.sp_dropdistributiondb
                    @database = @name

                IF @@ERROR <> 0 OR @retcode <> 0
                BEGIN
                    CLOSE hCdropdistributor
                    DEALLOCATE hCdropdistributor
                    RETURN (1)
                END
                FETCH hCdropdistributor INTO @name
            end

            CLOSE hCdropdistributor
            DEALLOCATE hCdropdistributor
        end
    end
    
    -- If everything should be cleaned up when we reach here with @no_checks = 1
    /*
    ** If local distributor, check if there are any distributor databases
    */
    IF UPPER(@distributor) = UPPER(@@SERVERNAME) 
    BEGIN
        IF EXISTS (SELECT * FROM msdb..MSdistributiondbs)
        BEGIN
            RAISERROR (14121, 16, -1, @distributor)
            RETURN(1)
        END
    END
    ELSE
    begin
        -- Check to see if there are database published.
        if exists (SELECT * FROM master..sysdatabases      
            WHERE (category & @transpublishdb_bit) <> 0 or 
            (category & @mergepublishdb_bit) <> 0)
        begin
            raiserror(21045, 16, -1)
            return(1)
        end

        -- Check to see if there are subscribers defined.
        if exists (SELECT *
                     FROM master..sysservers
                    WHERE srvstatus & 4 <> 0)
        begin
            raiserror(21008, 16, -1)
            return(1)
        end
    end


    /*
    ** if @ignore_distributor = 1, we are in bruteforce cleanup mode, don't do RPC.
    */
    if @ignore_distributor = 0 
    begin
        /*
        ** Get distribution server information
        */
        EXEC @retcode = dbo.sp_helpdistributor @publisher = @@SERVERNAME,
            @distribdb = @distribdb OUTPUT
        IF @@error <> 0 OR @retcode <> 0
        BEGIN
            RAISERROR (14071, 16, -1)
            RETURN (1)
        END

        IF @distribdb is NOT NULL
        BEGIN
            /* 
            ** Deactivate the dist publisher at the  distributor 
            ** Only do this if @distribdb is NOT NULL, which means the dist publisher
            ** if defined.
            */
            SELECT @proc = RTRIM(@dist_rpcname) + '.master.dbo.sp_changedistpublisher'
                EXECUTE @retcode = @proc @@SERVERNAME, 'active','false'
            IF @@error <> 0 OR @retcode <> 0
            BEGIN
                RETURN (1)
            END
        END
    end


    /*
    ** Clear the server option to indicate that this is a distributor.
    */
    EXECUTE @retcode = dbo.sp_serveroption @dist_rpcname, 'dist', false
    IF @@error <> 0 OR @retcode <> 0
        BEGIN
            RETURN(1)
        END

    -- Prevent dropping local server entry accidentally if user 
    -- set 'dist' server option on local server.
    if UPPER(@dist_rpcname) <> UPPER(@@servername)
    begin
        exec @retcode = dbo.sp_dropserver @dist_rpcname, 'droplogins'
        IF @@error <> 0 OR @retcode <> 0
        BEGIN
            RETURN(1)
        END
    end


    -- Bug 26775 drop table after unmark distributor to prevent 
    -- sp_helpdist* failures.
    /* If local, Drop replication category and alerts */
    IF UPPER(@distributor) = UPPER(@@SERVERNAME)
    BEGIN

		/* Cannot drop login, it might be in use by a system process 
        if exists (select * from master..syslogins where loginname = @distributor_login)
        begin

			execute @retcode = dbo.sp_droplogin 'distributor_admin'
			if @@error <> 0 or @retcode <> 0
				RETURN (1)
		end
		*/

        -- Drop Distributor Alerts and Jobs
        exec @retcode = dbo.sp_MSdrop_distributor_alerts_and_responses
        IF @@ERROR <> 0 or @retcode <> 0
        BEGIN
            return (1)            
        END

        -- Drop the two system tables.
        if exists (select * from msdb..sysobjects where name = 'MSdistpublishers'
            and xtype = 'U')
            drop table msdb..MSdistpublishers
    
        if @@error <> 0 
            return 1 ;

        if exists (select * from msdb..sysobjects where name = 'MSdistributiondbs'
            and xtype = 'U')
            drop table msdb..MSdistributiondbs

        if @@error <> 0
            return 1 ;

        if exists (select * from msdb..sysobjects where name = 'MSdistributor'
                and xtype = 'U')
            drop table msdb..MSdistributor

        if @@error <> 0
            return 1 ;

        if exists (select * from msdb..sysobjects where name = 'sysreplicationalerts'
                and xtype = 'U')
            drop table msdb..sysreplicationalerts

        if @@error <> 0
            return 1 ;


        if exists (select * from msdb..sysobjects where name = 'MSagent_profiles'
            and xtype = 'U')
            drop table msdb..MSagent_profiles

        if @@error <> 0
            return 1 ;


       if exists (select * from msdb..sysobjects where name = 'MSagent_parameters'
                and xtype = 'U')
            drop table msdb..MSagent_parameters

        if @@error <> 0
            return 1 ;

    END

    -- Nnregister sp_MSrepl_startup as a startup stored procedure
    exec @retcode = dbo.sp_procoption 'sp_MSrepl_startup', 'startup', 'false' 
    if @@error <> 0 or @retcode <> 0
        return 1

    RETURN (0)        
GO

dump tran master with NO_LOG
go

raiserror('Creating procedure sp_helpdistributiondb', 0,1)
go

CREATE PROCEDURE sp_helpdistributiondb (
    @database sysname = '%'
    ) AS

    SET NOCOUNT ON

    declare @retcode int
    declare @cmd    nvarchar(500)

    /*
    ** Check to make sure this is a distributor
    */
    IF NOT EXISTS (select * from master..sysservers
              where UPPER(datasource) = UPPER(@@SERVERNAME)
                 AND srvstatus & 8 <> 0)
    begin
    if @database <> '%' 
    begin
            raiserror (14114, 16, -1, @@SERVERNAME)
            return(1)
    end
    else
       return(0)
    end

    IF NOT EXISTS (select * from msdb..sysobjects where name = 'MSdistributiondbs' and type = 'U')
    begin
        raiserror (14071, 16, -1)
        return(1)
    end    

    /*
    ** Check if database is configured as a distributor database
    */
    IF @database <> '%' AND NOT EXISTS (select * from msdb..MSdistributiondbs where name = @database)
    begin
        raiserror (14117, 16, -1, @database)
        return(1)
    end    

    -- Begin from sp_helpdb

    /*  Create temp table before any DMP to enure dynamic
    **  Since we examine the status bits in sysdatabase and turn them
    **  into english, we need a temporary table to build the descriptions.
    */
    create table #spdbdesc
    (
        dbid    smallint    null,
        dbdesc  nvarchar(175)   null
    )

    /* 
    ** Since we need to execute dynamic SQL to get the list of files, create a temp 
    ** table to keep file descriptions
    */
    create table #spfiledesc
    (
        dbid    smallint        not null,
        fileid  smallint        not null,
        status  int        not null,
        size    int             not null,
        name    sysname         not null,
        filename nvarchar(260)   not null
    )   

    /*
    **  Initialize #spdbdesc from sysdatabases
    */
    insert into #spdbdesc (dbid)
            select dbid from master.dbo.sysdatabases d, msdb.dbo.MSdistributiondbs dist
                where d.name like @database and
                dist.name = d.name and 
                (isnull(databaseproperty(d.name, N'issuspect'), 0) = 0 and isnull(databaseproperty(d.name, N'isshutdown'), 0) = 0)

    declare @name sysname

    /* 
    ** Insert the list of all files into #spfiledesc
    */
    declare c1 CURSOR LOCAL FAST_FORWARD FOR 
        select db_name (dbid) from #spdbdesc
    open c1
    fetch c1 into @name
    while @@fetch_status >= 0
    begin

        /* Insert row for each database */
        select @cmd =  ('insert into #spfiledesc
                select db_id ('''+ @name + '''), fileid, status, size, RTRIM(name), RTRIM(filename) from' 
                + ' ' + QUOTENAME(@name) + '.dbo.sysfiles')
        exec (@cmd)
        fetch c1 into @name
    end
    deallocate c1

    SELECT dist.name, min_distretention, max_distretention, history_retention,
        'history_cleanup_agent' =  formatmessage (20567, dist.name),
        'distributor_cleanup_agent' = formatmessage(20568, dist.name),
        'status'= 0, 

        -- Refer to sp_helpdb for the following query.
        'data_folder' = substring(v_data.filename, 1, len(v_data.filename) - charindex('\', reverse(v_data.filename))),
        'data_file' = right(v_data.filename, charindex('\', reverse(v_data.filename))-1),
        'data_file_size' = CONVERT(int, (select low from master.dbo.spt_values
            where type = 'E'
                and number = 1)
            * convert(dec(15), v_data.size)/ 1048576),
    
        'log_folder' = substring(v_log.filename, 1, len(v_log.filename) - charindex('\', reverse(v_log.filename))),
        'log_file' = right(v_log.filename, charindex('\', reverse(v_log.filename))-1),
        'log_file_size' = CONVERT(int, (select low from master.dbo.spt_values
            where type = 'E'
                and number = 1)
            * convert(dec(15), v_log.size)/ 1048576)
        
        FROM msdb.dbo.MSdistributiondbs dist,
        master.dbo.sysdatabases d, #spfiledesc v_data,
        #spfiledesc v_log
        WHERE dist.name LIKE @database
            
            and v_data.dbid = d.dbid 
            and v_data.dbid > 0 
            and v_data.status & 2 = 2
            and v_data.status & 0x40 = 0 -- data
            and v_data.fileid = (select min(v_data2.fileid) from #spfiledesc v_data2 where
                    v_data2.dbid = d.dbid 
                and v_data2.dbid > 0    
                and v_data2.status & 2 = 2
                and v_data2.status & 0x40 = 0 ) -- data

            
            and v_log.dbid = d.dbid 
            and v_log.dbid > 0  
            and v_log.status & 2 = 2
            and v_log.status & 0x40 = 0x40 -- log
            and v_log.fileid = (select min(v_log2.fileid) from #spfiledesc v_log2 where
                    v_log2.dbid = d.dbid 
                and v_log2.dbid > 0 
                and v_log2.status & 2 = 2
                and v_log2.status & 0x40 = 0x40 ) -- log

            and d.name = dist.name
GO
 

dump tran master with no_log
GO

raiserror('Creating procedure sp_changedistributiondb', 0,1)
go

CREATE PROCEDURE sp_changedistributiondb (
    @database sysname,
    @property sysname     = NULL,     /* The property to change */
    @value nvarchar(255)     = NULL      /* The new property value */
    ) AS

    SET NOCOUNT ON

    /*
    ** Declarations.
    */
    DECLARE @distributor sysname
    DECLARE @min_distretention     int
    DECLARE @max_distretention     int
    DECLARE @retcode             int
    DECLARE @new_min_distretention     int
    DECLARE @new_max_distretention     int
    DECLARE @new_history_retention     int
    DECLARE @agentname nvarchar(100)
    DECLARE @command nvarchar(255)
    DECLARE @security_mode int
    DECLARE @distbit int

    SELECT @distbit = 16

    /*
    ** Parameter Check:  @property.
    ** If the @property parameter is NULL, print the options.
    */

    IF @property IS NULL
        BEGIN
            CREATE TABLE #tab1 (properties sysname NOT NULL)
            INSERT INTO #tab1 VALUES ('min_distretention')
            INSERT INTO #tab1 VALUES ('max_distretention')
            INSERT INTO #tab1 VALUES ('history_retention')
            SELECT * FROM #tab1
            RETURN (0)
        END

    /*
    ** Parameter Check:  @property.
    ** Check to make sure that @property is a valid property in
    ** sysarticles.
    */
    IF @property IS NULL OR LOWER(@property) NOT IN ('min_distretention',
                                                     'max_distretention',
                                                     'history_retention')
             
        BEGIN

            RAISERROR (14115, 16, -1, 
            '''min_distretention'', ''max_distretention'' or ''history_retention''')
            RETURN (1)
        END


    /*
    ** Check to make sure this is a distributor
    */
    IF NOT EXISTS (SELECT * FROM master..sysservers
              WHERE UPPER(datasource) = UPPER(@@SERVERNAME)
                 AND srvstatus & 8 <> 0)
    BEGIN
        RAISERROR (14114, 16, -1, @@SERVERNAME)
        RETURN(1)
    END

    /*
    ** Check if database is configured as a distributor database
    */
    IF NOT EXISTS (SELECT * FROM master..sysdatabases
              WHERE name = @database
                 AND category & @distbit <> 0)
    BEGIN
        RAISERROR (14117, 16, -1, @database)
        RETURN(1)
    END
    
    /*
    ** Change the property.
    */
    IF LOWER(@property) = 'min_distretention'
        BEGIN
            IF @value IS NULL
                BEGIN
                    RAISERROR (14043, 16, -1, '@value') 
                    RETURN (1)
                END

            /*
            ** Set the MinDistRetention registry key value
            */
            SELECT @new_min_distretention = CONVERT(int, @value)

            /*
            ** Get MaxDistRetention value
            */
            SELECT @max_distretention = max_distretention FROM msdb..MSdistributiondbs
                WHERE name = @database
                
            /* 
            ** Check for invalid retention values 
            */
            IF @new_min_distretention < 0
                BEGIN
                       RAISERROR(14106, 16, -1)
                    RETURN (1)
                END
            IF @new_min_distretention > @max_distretention
                BEGIN
                    RAISERROR(14107, 16, -1) 
                    RETURN (1)
                END

            UPDATE msdb..MSdistributiondbs SET min_distretention = @new_min_distretention
                WHERE name = @database
            IF @@error <> 0 
                BEGIN
                    RETURN (1)
                END

            /*
            ** Update Distribution Cleanup agent 
            */
    		select @agentname = name from msdb..sysjobs j, msdb..sysjobsteps s where 
			j.job_id = s.job_id and
			j.category_id = 11 and
			s.database_name = @database
        
			SELECT @command =  'EXEC dbo.sp_MSdistribution_cleanup @min_distretention = ' + 
                CONVERT(nvarchar(12), @new_min_distretention) + ', @max_distretention = ' +
                CONVERT(nvarchar(12), @max_distretention)
            EXEC @retcode = msdb.dbo.sp_update_jobstep @job_name = @agentname, @step_id = 1, 
                @command = @command
            IF @@error <> 0 OR @retcode <> 0
               RETURN(1)

        END

    IF LOWER(@property) = 'max_distretention'
        BEGIN
            IF @value IS NULL
                BEGIN
                    RAISERROR (14043, 16, -1, '@value') 
                    RETURN (1)
                END

            /*
            ** Set the MaxDistRetention registry key value
            */
            SELECT @new_max_distretention = CONVERT(int, @value)

			select @command = @database + '..sp_MSValidate_Retention'
			exec @retcode = @command @new_max_distretention
			if @@ERROR <>0 or @retcode<>0
				BEGIN
					RAISERROR(21086, 16, -1)
					RETURN (1)
				END

            /*
            ** Get MinDistRetention value
            */
            SELECT @min_distretention = min_distretention FROM msdb..MSdistributiondbs
                WHERE name = @database

            /* 
            ** Check for invalid retention values 
            */
            IF @new_max_distretention < 0
                BEGIN
                       RAISERROR(14106, 16, -1)
                    RETURN (1)
                END
            IF @new_max_distretention < @min_distretention
                BEGIN
                    RAISERROR(14107, 16, -1) 
                    RETURN (1)
                END

            UPDATE msdb..MSdistributiondbs SET max_distretention = @new_max_distretention
                WHERE name = @database
            IF @@error <> 0 
                BEGIN
                    RETURN (1)
                END
            /*
            ** Update Distribution Cleanup agent 
            */
			select @agentname = name from msdb..sysjobs j, msdb..sysjobsteps s where 
				j.job_id = s.job_id and
				j.category_id = 11 and
				s.database_name = @database
            SELECT @command =  'EXEC dbo.sp_MSdistribution_cleanup @min_distretention = ' + 
                CONVERT(nvarchar(12), @min_distretention) + ', @max_distretention = ' +
                CONVERT(nvarchar(12), @new_max_distretention)
            EXEC @retcode = msdb.dbo.sp_update_jobstep @job_name = @agentname, @step_id = 1, 
                @command = @command
            IF @@error <> 0 OR @retcode <> 0
               RETURN(1)
        END

    IF LOWER(@property) = 'history_retention'
        BEGIN
            IF @value IS NULL
                BEGIN
                    RAISERROR (14043, 16, -1, '@value') 
                    RETURN (1)
                END

            /*
            ** Set the HistoryRetention registry key value
            */
            SELECT @new_history_retention = CONVERT(int, @value)

            UPDATE msdb..MSdistributiondbs SET history_retention = @new_history_retention
                WHERE name = @database
            IF @@error <> 0 
                BEGIN
                    RETURN (1)
                END

            /*
            ** Update History Cleanup agent 
            */
			select @agentname = name from msdb..sysjobs j, msdb..sysjobsteps s where 
				j.job_id = s.job_id and
				j.category_id = 12 and
				s.database_name = @database
            SELECT @command =  'EXEC dbo.sp_MShistory_cleanup @history_retention = ' + 
                CONVERT(nvarchar(12), @new_history_retention)
            EXEC @retcode = msdb.dbo.sp_update_jobstep @job_name = @agentname, @step_id = 1, 
                @command = @command
            IF @@error <> 0 OR @retcode <> 0
               RETURN(1)

        END




    /*
    ** Return succeed.
    */
    RAISERROR (14105, 10, -1, @property)
    RETURN (0)
go
 
raiserror('Creating procedure sp_dropdistributiondb', 0,1)
go

CREATE PROCEDURE sp_dropdistributiondb (
    @database sysname        
    
) AS

    SET NOCOUNT ON
    /*
    ** Declarations.
    */
    DECLARE @retcode int
    DECLARE @agentname nvarchar(100)
    DECLARE @reg_key nvarchar(255)
    DECLARE @security_mode int
    DECLARE    @distbit int
    DECLARE @distpublisher sysname
    DECLARE @distdb sysname
    DECLARE @device_name sysname
    DECLARE @command nvarchar(255)

    SELECT @distbit = 16

    /*
    ** Check to make sure this is a distributor
    */
    IF NOT EXISTS (SELECT * FROM master..sysservers
              WHERE UPPER(datasource) = UPPER(@@SERVERNAME)
                 AND srvstatus & 8 <> 0)
    BEGIN
        RAISERROR (14114, 16, -1, @@SERVERNAME)
        RETURN(1)
    END

    /*
    ** Check if database is configured as a distributor database
    */
    IF NOT EXISTS (SELECT * FROM msdb..MSdistributiondbs WHERE name = @database)
    BEGIN
        RAISERROR (14117, 16, -1, @database)
        RETURN(1)
    END

    /*
    ** Check if any DistPublishers are using this database
    */
    IF EXISTS (SELECT * FROM msdb..MSdistpublishers WHERE
        distribution_db = @database)
    BEGIN
        RAISERROR (14120, 16, -1, @database)
        RETURN (1)
    END
    
	/*
	** Check if the DB is being currently used
	*/
	IF EXISTS (SELECT * FROM master..sysprocesses WHERE
		dbid = DB_ID(@database))
	BEGIN
		RAISERROR (21122, 16, 1, @database)
		RETURN (1)
	END
	   
	/*
	** Do distribution cleanup the final time
	** This should also remove the REPLDATA files
	*/
	SELECT @command = QUOTENAME(@database) + 
		'.dbo.sp_MSdistribution_cleanup @min_distretention = 0, @max_distretention = 0'
	SELECT @command = 'EXEC ' + @command
	EXEC (@command)
	IF (@@ERROR <> 0)
	BEGIN
		RETURN (1)
	END

    /*
    ** Drop the history cleanup agent.
    */
    SELECT @agentname = formatmessage (20567, @database)
    IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @agentname and
        originating_server = '(local)')
    BEGIN
        EXEC @retcode = msdb.dbo.sp_delete_job 
            @job_name = @agentname
        IF @@ERROR <> 0 or @retcode <> 0
        BEGIN
            RETURN(1)
        END
    END

    /*
    ** Drop the distribution cleanup agent.
    */
    SELECT @agentname = formatmessage (20568, @database)
    IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @agentname and
        originating_server = '(local)')
    BEGIN
        EXEC @retcode = msdb.dbo.sp_delete_job 
            @job_name = @agentname
        IF @@ERROR <> 0 or @retcode <> 0
        BEGIN
            RETURN(1)
        END
    END

    /*
    ** Update sysdatabase category bit before dropping the database
    ** Otherwise, the database can not be dropped.
    **
    */
    UPDATE master..sysdatabases SET category = category & ~@distbit WHERE name = @database
    IF @@ERROR <> 0
        BEGIN
            RETURN (1)
        END


    -- Drop the distributor db if it exists
    IF EXISTS (SELECT * FROM master..sysdatabases WHERE name = @database)
    BEGIN

        CREATE TABLE #db_existed
        (
        db_existed bit  NOT NULL
        )

        /* Get version stamp */
        SELECT @command = 'INSERT INTO #db_existed SELECT db_existed FROM ' +
            QUOTENAME(@database) + '..MSrepl_version'
    
        EXEC(@command)
        IF @@ERROR <> 0
        BEGIN
            RETURN(1)       
        END

        -- Drop the distribution db only if it is created in sp_adddistributiondb.
        IF NOT EXISTS (SELECT * FROM #db_existed where db_existed = 0x1)
        BEGIN
    
            /* Save the device info before dropping the database */
            CREATE TABLE #distdbdevices (name sysname  NOT NULL)

            /* Drop distributor devices */
            /* Query is copied from sp_helpdb */
            SELECT @command = 
                'INSERT INTO #distdbdevices select DISTINCT name from ' + QUOTENAME(@database) + '.dbo.sysfiles'
            EXEC (@command)
            IF @@ERROR <>0
            BEGIN
                RETURN(1)      
            END

            /*
            ** Drop the distribution database
            */
			SELECT @command = 'drop database ' + QUOTENAME(@database)
			EXEC (@command)
            IF @@ERROR <> 0
                BEGIN
                    /* Mark the database as distribution database again 
                    ** Otherwise, this sp will fail when it is reentered.
                    ** It is often the case that if there's an open session
                    ** on the database, it can not be dropped.
                    */
                    RETURN(1)
                END

            /* Drop distributor devices */
            /* Query is copied from sp_helpdb */
            /* SQL SERVER 7.0 may drop some auto generated device files, drop drop them here
               again
            */
            DECLARE hCdropdistributiondb CURSOR LOCAL FAST_FORWARD FOR
                SELECT DISTINCT dd.name FROM #distdbdevices dd, master.dbo.sysdevices ss
                    WHERE ss.name = dd.name
            FOR READ ONLY
    
            OPEN hCdropdistributiondb
            FETCH hCdropdistributiondb INTO @device_name

            WHILE (@@fetch_status <> -1)
            BEGIN
                /* 
                ** Device may be used by other databases
                ** Ignore all errors 
                */
                EXEC dbo.sp_dropdevice @device_name, DELFILE
                FETCH hCdropdistributiondb INTO @device_name
            END

            CLOSE hCdropdistributiondb
            DEALLOCATE hCdropdistributiondb

        END
    END
    

    /*
    ** Delete the DistributionDB entry
    */

    DELETE msdb.dbo.MSdistributiondbs where name = @database
    IF @@error <> 0 OR @retcode <> 0
    BEGIN
        RETURN(1)
    END
    

    RETURN (0)
                
GO
 
dump tran master with no_log
GO
raiserror('Creating procedure sp_adddistributiondb', 0,1)
go

CREATE PROCEDURE sp_adddistributiondb (
    @database sysname,
    @data_folder nvarchar(255) = NULL,
    @data_file nvarchar(255) = NULL,            /* physical file name */
    @data_file_size int = 2,                    /* Default: 2MB */            
    @log_folder nvarchar(255) = NULL,
    @log_file nvarchar(255) = NULL,             /* physical file name */
    @log_file_size int = 0,
    @min_distretention int = 0,                 /* min distribution retention period in hours */
    @max_distretention int = 72,                /* max distribution retention period in hours */
    @history_retention int = 48,                /* history retention period in hours */
    @security_mode int = 0,                     /* distributor login security 0 standard 1 integrated */
    @login sysname = 'sa',                      /* standard login name */
    @password sysname = NULL,                   /* standard login password */
    @createmode int = 0  /* 0: use create db for attach (recommended), 
                            1: create db or use existing but no attach (this is the old way), 
                            2: create for instdist and detach only */
    ) AS

    SET NOCOUNT ON

    /*
    ** Declarations.
    */
    DECLARE @data_path nvarchar(512)
    DECLARE @log_path nvarchar(512)
    
    DECLARE @data_path_quoted_for_copy nvarchar(512)
    DECLARE @log_path_quoted_for_copy nvarchar(512)

    DECLARE @logical_data_file nvarchar(255)
    DECLARE @logical_log_file nvarchar(255)
    DECLARE @canneddbdata_file nvarchar(255)
    DECLARE @canneddblog_file nvarchar(255)
    DECLARE @filecopy_cmd nvarchar(255)
    DECLARE @file_exists int
    DECLARE @data_file_preexists int
    DECLARE @log_file_preexists int
    DECLARE @osql_cmd nvarchar(255)
	DECLARE @osql_for_nt int
    DECLARE @devnum int
    --DECLARE @num_pages int
    DECLARE @retcode int
    DECLARE @reg_key nvarchar(255)
    DECLARE @agentname nvarchar(100)
    DECLARE @command nvarchar (2048)
    DECLARE @distbit int
    DECLARE @install_path nvarchar(255)
    DECLARE @mssql_data_path nvarchar(255)
    DECLARE @on_clause nvarchar(512)
    DECLARE @logon_clause nvarchar(512)
    DECLARE @distproc nvarchar(255)
    DECLARE @major_version int
    DECLARE @db_exists bit
    DECLARE @trunc_log_bit int
    DECLARE @description nvarchar(100)
    DECLARE @category_name sysname
    DECLARE @createmode_attach int
    DECLARE @createmode_noattach int
    DECLARE @createmode_fordetach int

    DECLARE @filegrowth nvarchar(10)
    DECLARE @data_file_size_str nvarchar(10)
    DECLARE @log_file_size_str nvarchar(10)
    DECLARE @platform_nt binary

    --DECLARE @max_datafile_size int
    --DECLARE @max_logfile_size int
    
	IF @password = N''
		select @password = [REDACTED]

    select @platform_nt = 0x1
    select @filegrowth = N'512KB'

    -- on error, delete the data and log files only if they didn't pre-exist.
    -- by default, assume they pre-exist.
    select @data_file_preexists = 1
    select @log_file_preexists = 1

    if (@data_file_size IS NULL) or (@data_file_size = 0)
        select @data_file_size_str = N'512KB'
    else
        select @data_file_size_str = convert(nvarchar(10), @data_file_size)

    if (@log_file_size IS NULL) or (@log_file_size = 0)
        select @log_file_size_str = N'512KB'
    else
        select @log_file_size_str = convert(nvarchar(10), @log_file_size)
    
    --if (@data_file_size > 16)
    --  select @max_datafile_size = @data_file_size
    --else
    --  select @max_datafile_size = 16
    
    --if (@log_file_size > 16)
    --  select @max_logfile_size = @log_file_size
    --else
    --  select @max_logfile_size = 16

    select @createmode_attach = 0, @createmode_noattach = 1, @createmode_fordetach = 2
    SELECT @trunc_log_bit = 8
    SELECT @distbit = 16

    if (@createmode <> @createmode_fordetach)
    begin
    
        /* 
        ** Check if replication components are installed on this server
        */
        exec @retcode = dbo.sp_MS_replication_installed
        if (@retcode <> 1)
        begin
            return (1)
        end
    
        /* 
        ** Check for invalid security modes
        */
        IF @security_mode < 0 OR @security_mode > 1
        BEGIN
            RAISERROR(14109, 16, -1)
            RETURN (1)
        END

        IF ( ( @platform_nt != platform() & @platform_nt ) and @security_mode = 1)
        BEGIN
            RAISERROR(21038, 16, -1)
            RETURN (1)
        END
    
        /* 
        ** Check for invalid retention values 
        */
        IF @min_distretention < 0 OR @max_distretention < 0 
        BEGIN
            RAISERROR(14106, 16, -1)
            RETURN (1)
        END
        IF @min_distretention > @max_distretention
        BEGIN
            RAISERROR(14107, 16, -1) 
            RETURN (1)
        END

        /*
        ** Check to make sure this is a distributor
        */
        IF NOT EXISTS (SELECT * FROM master..sysservers
              WHERE UPPER(datasource) = UPPER(@@SERVERNAME)
                 AND srvstatus & 8 <> 0)
        BEGIN
            RAISERROR (14114, 16, -1, @@SERVERNAME)
            RETURN(1)
        END
    
        /*
        ** Check if database is already configured as a distributor database
        */
        IF EXISTS (SELECT * FROM msdb..MSdistributiondbs WHERE name = @database)
        BEGIN
            RAISERROR (14119, 16, -1, @database)
            RETURN(1)
        END    
    end

    /* 
    ** Get installation path
    */
    EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
              'SOFTWARE\Microsoft\MSSQLServer\Setup',
              'SQLPath',
            @param = @install_path OUTPUT
    IF @retcode <> 0 or @install_path is NULL or @install_path=''
    BEGIN
        GOTO UNDO       
    END

    /*
    ** Get the MSSQL DATA path. Note that users can have a SQLDataRoot directory different from SQLPath
    */
    EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
              'SOFTWARE\Microsoft\MSSQLServer\Setup',
              'SQLDataRoot',
            @param = @mssql_data_path OUTPUT
    IF @retcode <> 0 or @mssql_data_path is NULL or @mssql_data_path = ''
    BEGIN
        GOTO UNDO       
    END

    IF @data_folder IS NULL or @data_folder = ''
        select @data_folder = @mssql_data_path + '\DATA'

    IF @log_folder IS NULL or @log_folder = ''
        select @log_folder = @mssql_data_path + '\DATA'

    IF @data_file IS NULL
        SELECT @data_file = @database + '.MDF'

    IF @log_file IS NULL
        SELECT @log_file = @database + '.LDF'

	if substring(@data_folder, len(@data_folder), 1) = '\'
        select @data_folder = substring (@data_folder, 1, len(@data_folder) -1)
	if substring(@log_folder, len(@log_folder), 1) = '\'
        select @log_folder = substring (@log_folder, 1, len(@log_folder) -1)

    SELECT @data_path = @data_folder + '\' + @data_file
    SELECT @log_path = @log_folder + '\' + @log_file

    SELECT @data_path_quoted_for_copy = '"' + @data_folder + '"' + '\' + '"' + @data_file + '"'
    SELECT @log_path_quoted_for_copy = '"' + @log_folder + '"' + '\' + '"' + @log_file + '"'

    select @logical_data_file = @database

    /* 
    ** Bug 40096: Truncate the logical log file name back to 128 characters
    **            long so the 'CREATE DATABASE' statement won't complain.
    */
    /* LEN(@logical_log_file) = LEN(@database) + LEN('_log') and
       LEN(@logical_log_file) <= 128 implies 
       LEN(@database) <=124 */
    IF (LEN(@database) > 124)
        SELECT @logical_log_file = SUBSTRING(@database, 1, 124) + '_log'  
    ELSE 
        SELECT @logical_log_file = @database + '_log'

    if (@createmode = @createmode_attach)
    begin
        select @canneddbdata_file = @mssql_data_path + '\DATA\DISTMDL.MDF'
        select @canneddblog_file = @mssql_data_path + '\DATA\DISTMDL.LDF'

        exec @file_exists = dbo.sp_MSexists_file @canneddbdata_file, 'DISTMDL.MDF'
        if (@file_exists = 0)
        begin
            /* Fallback to mode where instdist.sql needs to be run */
            select @createmode = @createmode_noattach
        end

        exec @file_exists = dbo.sp_MSexists_file @canneddblog_file, 'DISTMDL.LDF'
        if (@file_exists = 0)
        begin
            /* Fallback to mode where instdist.sql needs to be run */
            select @createmode = @createmode_noattach
        end
    end

    /*
    ** Create the distributor database if it does not exist
    */
    IF NOT EXISTS (SELECT * from master..sysdatabases WHERE name = @database) AND (@createmode <> @createmode_attach)
    BEGIN

        IF @logical_data_file IS NOT NULL AND NOT EXISTS (SELECT * FROM master..sysdevices WHERE name = @logical_data_file)
        BEGIN
            SELECT @on_clause = ' ON (NAME =''' + @logical_data_file + ''',FILENAME=''' + @data_path + 
                ''', SIZE=' + @data_file_size_str + ', FILEGROWTH=' + @filegrowth + ', MAXSIZE = UNLIMITED)'
        END

        IF @logical_log_file IS NOT NULL AND NOT EXISTS (SELECT * FROM master..sysdevices WHERE name = @logical_log_file)
        BEGIN
            SELECT @logon_clause = ' LOG ON (NAME =''' + @logical_log_file + ''',FILENAME=''' + @log_path + 
                ''', SIZE=' + @log_file_size_str + ', FILEGROWTH=' + @filegrowth + ', MAXSIZE= UNLIMITED)'          
        END

        /*
        ** Create distributor database
        */
        SELECT @command = 'USE master  CREATE DATABASE ' +  QUOTENAME(@database) + 
            + isnull(@on_clause, ' ') + isnull(@logon_clause, ' ')

        EXEC (@command)
        IF @@ERROR <> 0
            RETURN (1)
        SELECT @db_exists = 0
    END
    ELSE IF NOT EXISTS (SELECT * from master..sysdatabases WHERE name = @database) AND (@createmode = @createmode_attach)
    BEGIN
    /* DO THE CREATE DATABASE FOR ATTACH STUFF */
        
        exec @data_file_preexists = dbo.sp_MSexists_file @data_path_quoted_for_copy, @data_file
        if (@data_file_preexists = 1)
        begin
            raiserror(5170, 16, -1, @data_path)
            return 1
        end
    
        SELECT @on_clause = ' ON (NAME = ''' + @logical_data_file + ''', FILENAME=''' + @data_path + ''')'
        
        exec @log_file_preexists = dbo.sp_MSexists_file @log_path_quoted_for_copy, @log_file
        if (@log_file_preexists = 1)
        begin
            raiserror(5170, 16, -1, @log_path)
            return 1
        end

        SELECT @logon_clause = ' LOG ON (NAME = ''' + @logical_log_file + ''', FILENAME=''' + @log_path + ''')'

        select @filecopy_cmd = 'copy ' + @canneddbdata_file + ' ' + @data_path_quoted_for_copy
        EXEC @retcode = master..xp_cmdshell @filecopy_cmd, NO_OUTPUT
        IF @retcode <> 0 OR @@ERROR <> 0
        BEGIN
            RAISERROR (14113, 16, -1, @filecopy_cmd, 'instdist.out')
            return (1)
        END

        select @filecopy_cmd = 'copy ' + @canneddblog_file + ' ' + @log_path_quoted_for_copy
        EXEC @retcode = master..xp_cmdshell @filecopy_cmd, NO_OUTPUT
        IF @retcode <> 0 OR @@ERROR <> 0
        BEGIN
            RAISERROR (14113, 16, -1, @filecopy_cmd, 'instdist.out')
            return (1)
        END

        /*
        ** Create distributor database
        */
        SELECT @command = 'USE master  CREATE DATABASE ' +  QUOTENAME(@database) + 
            + @on_clause + @logon_clause + ' FOR ATTACH'
        dbcc traceon (1806)
        EXEC (@command)
        IF @@ERROR <> 0
        begin
            dbcc traceoff(1806)
            RETURN (1)
        end
        dbcc dbreindexall(@database, 240)
        dbcc traceoff(1806)

        SELECT @db_exists = 0
    END
    ELSE
    BEGIN
        SELECT @db_exists = 1
    END

    -- Must make the dist db owned by sa so that the sps in it can select from
    -- security cache tables in tempdb by owership chain rule.
    declare @retcode2 int
    select @retcode2 = 0
    select @distproc = QUOTENAME(@database) + '.dbo.sp_executesql'
    SELECT @command = 
        -- If the db is created by sa or from attach, sa is dbo already.
        -- sp_changedbowner will fail is the new owner is an user in the db already.
        ' if not exists (select * from sysusers where sid = 0x01) ' +
        ' exec @retcode2 = dbo.sp_changedbowner ''sa'''
    EXEC @retcode = @distproc @command, N'@retcode2 int output', @retcode2 output
    IF @retcode <> 0 or @retcode2 <> 0 or @@ERROR <> 0
    BEGIN
        GOTO UNDO
    END

    /* Set the database option truncate log on checkpoint & turn off autoclose which is default of win9x*/
    IF EXISTS (SELECT * FROM master.dbo.sysdatabases WHERE 
        name = @database AND
        (status & @trunc_log_bit) = 0 )   -- if its not already marked
    BEGIN
        EXEC @retcode = dbo.sp_dboption @database, 'trunc. log on chkpt.', 'true'
        IF @retcode <> 0 OR @@ERROR <> 0
        BEGIN
            GOTO UNDO
        END
    END

    EXEC @retcode = dbo.sp_dboption @database, 'autoclose', 'false'
        IF @retcode <> 0 OR @@ERROR <> 0
        BEGIN
            GOTO UNDO
        END

    /*
    **
    ** Update sysdatabase category bit
    ** This is to prevent user from dropping the database.
    **/
    if (@createmode <> @createmode_fordetach)
    begin
        UPDATE master..sysdatabases SET category = category | @distbit WHERE name = @database
        IF @@ERROR <> 0
        BEGIN
            GOTO UNDO
        END
    end

    /* 
    ** Install instdist.sql
    */

    if (@createmode <> @createmode_attach) OR (@db_exists = 1)
    begin
	if (( platform() & @platform_nt = @platform_nt ))
		select @osql_for_nt = 1
	else
		select @osql_for_nt = 0

        -- Always use integrated security on WINNT since @login passed-in is for remote 
        -- subscriber and may not have enough privilege to apply the script
        IF (@security_mode = 1 or @osql_for_nt = 1) AND NOT (@security_mode = 0 AND @createmode = 2)
		BEGIN
            SELECT @osql_cmd = '" "' + @install_path + '\binn\osql" -E ' 
		END
        ELSE
		BEGIN
        -- cannot specify -S w/ -E for local execution, SID does not map due to nofix bug
		if (@osql_for_nt = 1)
            SELECT @osql_cmd = '" "' + @install_path + '\binn\osql" -U' + @login + ' -P' + 
                isnull(@password,'') + ' -S' + @@SERVERNAME + ' '
		else
	    SELECT @osql_cmd = '"' + @install_path + '\binn\osql" -U' + @login + ' -P' + 
                isnull(@password,'') + ' -S' + @@SERVERNAME + ' '
		END
    
        select @osql_cmd = @osql_cmd + '-l60 -t60 '

        -- We must use -b option to make osql return error code !!
        SELECT @osql_cmd = @osql_cmd + 
            ' -d' + @database + ' -b ' +
            ' -i' + '"' + @install_path + '\install\instdist.sql"' + 
            ' -o' + '"' + @install_path + '\install\instdist.out"'

		if (@osql_for_nt = 1)
		BEGIN
	        SELECT @osql_cmd = @osql_cmd + ' "'
		END
    
        EXEC @retcode = master..xp_cmdshell @osql_cmd
        IF @retcode <> 0 OR @@ERROR <> 0
        BEGIN
            RAISERROR (14113, 16, -1, @osql_cmd, 'instdist.out')
            GOTO UNDO       
        END
    end
    
    if (@createmode <> @createmode_fordetach)
    begin
        /* Set db_existed bit in MSrepl_version */
        IF @db_exists = 1
        BEGIN
            SELECT @distproc = 'UPDATE ' +
                @database + '..MSrepl_version SET db_existed = 0x1'
    
            EXEC(@distproc)
            IF @@ERROR <> 0
            BEGIN
                GOTO UNDO       
            END
        END

        DELETE msdb.dbo.MSdistributiondbs WHERE name = @database
        IF @@ERROR <> 0
        BEGIN
            GOTO UNDO       
        END

        INSERT INTO msdb.dbo.MSdistributiondbs VALUES (
            @database, @min_distretention, @max_distretention, @history_retention
            )
        IF @@ERROR <> 0
        BEGIN
            GOTO UNDO       
        END

        -- This login need db_owner priviledge to call sps in distribution db
        declare @distributor_login sysname
        select @distributor_login = 'distributor_admin'

        select @command = quotename(@database) + '.dbo.sp_MSrepl_dbrole'
        exec @retcode = @command 'db_owner', @distributor_login, 'add'
        IF @@error <> 0 OR @retcode <> 0
            GOTO UNDO

        /*
        ** Create the history cleanup agent.
        */
        SELECT @agentname = formatmessage (20567, @database)
        SELECT @command =  'EXEC dbo.sp_MShistory_cleanup @history_retention = ' + 
            CONVERT(nvarchar(12), @history_retention)

        IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @agentname and
            originating_server = '(local)')
        BEGIN
            EXEC @retcode = msdb.dbo.sp_delete_job 
                @job_name = @agentname
            IF @@ERROR <> 0 or @retcode <> 0
            BEGIN
                GOTO UNDO
            END
        END

        set @description = formatmessage(20535)

        -- Get History Cleanup category name (assumes category_id = 12)
        select @category_name = name FROM msdb.dbo.syscategories where category_id = 12

        EXECUTE @retcode = dbo.sp_MSadd_repl_job @agentname,
        @subsystem = 'TSQL',
        @server = @@SERVERNAME,
        @databasename = @database,
        @description = @description,
        @freqtype = 4,    
        @freqsubtype = 4,         
        @freqsubinterval = 10,    /* Number of minutes between runs */ 
        @command = @command,
        @enabled = 1,
        @retryattempts = 0,
        @loghistcompletionlevel = 0,
        @category_name = @category_name
    
        IF @@ERROR <> 0 or @retcode <> 0
        BEGIN
            GOTO UNDO
        END

        /*
        ** Create the distribution cleanup agent.
        */
        SELECT @agentname = formatmessage (20568, @database)
        SELECT @command =  'EXEC dbo.sp_MSdistribution_cleanup @min_distretention = ' + 
            CONVERT(nvarchar(12), @min_distretention) + ', @max_distretention = ' +
            CONVERT(nvarchar(12), @max_distretention)

        IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @agentname and
            originating_server = '(local)')
        BEGIN
            EXEC @retcode = msdb.dbo.sp_delete_job 
                @job_name = @agentname
            IF @@ERROR <> 0 or @retcode <> 0
            BEGIN
                GOTO UNDO
            END
        END

        set @description = formatmessage(20541)
        -- Get Distribution Cleanup category name (assumes category_id = 11)
        select @category_name = name FROM msdb.dbo.syscategories where category_id = 11
    
        EXECUTE @retcode = msdb.dbo.sp_MSadd_repl_job @agentname,
        @subsystem = 'TSQL',
        @server = @@SERVERNAME,
        @databasename = @database,
        @description = @description,
        @freqtype = 4,    
        @freqsubtype = 4,         
        @freqsubinterval = 10,    /* Number of minutes between runs */ 
        @command = @command,
        @retryattempts = 0,
        @enabled = 0,
        @loghistcompletionlevel = 0,
        @category_name = @category_name
        IF @@ERROR <> 0 or @retcode <> 0
        BEGIN
            GOTO UNDO
        end
    end
    else
    begin
        /*detach */
        dbcc detachdb(@database)
    end
    
    RETURN(0)

UNDO:

    IF @db_exists = 0
        EXECUTE dbo.sp_dropdistributiondb @database

    /* Need to do it since sp_dropdistributiondb will fail in some cases */
    UPDATE master..sysdatabases SET category = category & ~@distbit WHERE name = @database
    
    DELETE msdb.dbo.MSdistributiondbs where name = @database

    /* drop the database and ignore error */
    IF @db_exists = 0 AND
        EXISTS (SELECT * from master..sysdatabases WHERE name = @database)
    BEGIN
        SELECT @command = 'USE master  DROP DATABASE ' +  QUOTENAME(@database) 
        EXEC (@command)
    END

    if (@createmode = @createmode_attach)
    begin
        if (@data_file_preexists = 0)
        begin
            select @command = 'del ' + @data_path_quoted_for_copy
            exec master..xp_cmdshell @command
            --ignore errors
        end
        if (@log_file_preexists = 0)
        begin
            select @command = 'del ' + @log_path_quoted_for_copy
            exec master..xp_cmdshell @command
            --ignore errors
        end
    end
        
    RETURN(1)        
GO
 
raiserror('Creating procedure sp_MSexists_file', 0,1)
go
create procedure sp_MSexists_file (@full_path nvarchar(512), @filename nvarchar(255))
AS
    SET NOCOUNT ON

    DECLARE @command nvarchar(512)
    DECLARE @retcode int
    DECLARE @platform_nt int

    select @platform_nt = 1

    if (@full_path is NULL)
    begin
        raiserror(14043,16,-1, '@full_path')
        return -1
    end

    if (@filename is NULL)
    begin
        raiserror(14043,16,-1, '@filename')
        return -1
    end

    select @command = 'dir ' + @full_path

    if (platform() & @platform_nt = @platform_nt)
    begin   
        exec @retcode = master..xp_cmdshell @command, 'no_output'
        if @@error <> 0
            return -1
        if @retcode <> 0 
            select @retcode = 0
        else
            select @retcode = 1
    end
    else
    begin
        create table #DirectoryTempTable(cmdoutput nvarchar(255) null)
        insert into #DirectoryTempTable exec master..xp_cmdshell @command

        /*
        ** The return code from xp_cmdshell is not a reliable way to check whether the file exists or
        ** not. It is always 0 on Win95 as long as xp_cmdshell succeeds.
        */  
    
        if exists (select * from #DirectoryTempTable where ltrim(rtrim(cmdoutput)) like '%'+@filename+'%') 
            and not exists (select * from #DirectoryTempTable where ltrim(rtrim(cmdoutput)) like '%File Not Found%')
            select @retcode = 1
        else 
            select @retcode = 0

        drop table #DirectoryTempTable
    end

    return @retcode
go


dump tran master with no_log
GO

raiserror('Creating procedure sp_dropdistpublisher', 0,1)
go

CREATE PROCEDURE sp_dropdistpublisher (
    @publisher sysname,         /* publisher server name */
    @no_checks bit = 0
        ) AS

    SET NOCOUNT ON

    DECLARE @distributor sysname
    DECLARE @distaccount nvarchar(127)
    DECLARE @proc nvarchar (255)
    DECLARE @retcode int
    DECLARE @privilege sysname
    DECLARE @reg_key nvarchar(255)
    DECLARE @return_status int
    DECLARE @foundSubscriber int 
    DECLARE @distribdb sysname
    DECLARE @command nvarchar(255)
    DECLARE @active_value int
    DECLARE @publish_bit int
    DECLARE @mergepub_bit int


    SELECT @return_status = 0
    SELECT @foundSubscriber = 0

    SELECT @publish_bit = 1
    SELECT @mergepub_bit = 4

    /*
    ** Parameter Check:  @publisher.
    ** Check to make sure that the publisher exists, that the name isn't
    ** NULL, and that the name conforms to the rules for identifiers.
    */

    IF @publisher IS NULL
        BEGIN
            RAISERROR (14043, 16, -1, '@publisher')
            RETURN (1)
        END

    EXECUTE @retcode = dbo.sp_validname @publisher

    IF @retcode <> 0
        RETURN (1)

    /*
    ** Get distribution server information for remote RPC
    ** agent verification.
    */
    EXEC @retcode = dbo.sp_helpdistributor @publisher = @publisher,
        @distributor = @distributor OUTPUT,
        @distribdb = @distribdb OUTPUT
    IF @@error <> 0 OR @retcode <> 0
        BEGIN
        RAISERROR (14071, 16, -1)
           RETURN (1)
    END

    /*
    ** Only a local distributor can be modified.
    */
    IF UPPER(@distributor) <> UPPER(@@SERVERNAME)
        BEGIN
        RAISERROR (14114, 16, -1, @@SERVERNAME)
        RETURN (1)
        END
 
    IF NOT EXISTS (SELECT *
    FROM msdb..MSdistpublishers
            WHERE UPPER(name) = UPPER(@publisher))
    BEGIN
        RAISERROR (14080, 11, -1)
        RETURN (1)
    END


    IF UPPER(@publisher) = UPPER(@@SERVERNAME)
    BEGIN
        /* 
        ** If @publisher is local, 
        ** 1. check to make sure there is no subscriber 
        ** for the publisher in the distribution database
        ** 2. check to make sure there are not database enabled for replication
        */
        -- Check to see if there are subscribers defined.
        if exists (SELECT *
                     FROM master..sysservers
                    WHERE srvstatus & 4 <> 0)
        begin
            raiserror(21047, 16, -1)
            return(1)
        end
        
        IF EXISTS (SELECT * FROM master..sysdatabases WHERE 
            (category & @publish_bit) <> 0 OR
            (category & @mergepub_bit) <> 0)
        BEGIN 
            RAISERROR (21033, 16, -1, @@SERVERNAME)
            RETURN (1)
        END
    END
    ELSE
    BEGIN
        if @no_checks = 0
        begin
            /* 
            ** If the publisher is remote, check the status of the distpublisher 
            ** The status will be inactive if the remote publisher dropped the
            ** distributor.
            */

            IF EXISTS (SELECT * FROM msdb.dbo.MSdistpublishers WHERE
                UPPER(name) = UPPER(@publisher) and active = 1)
            BEGIN
                RAISERROR (14098, 16, -1, @publisher, @@SERVERNAME)
                RETURN (1)
            END
        end
        else
        begin
            SELECT @command = @distribdb + '.dbo.sp_MSdistpublisher_cleanup'
            exec @retcode = @command @publisher
            if @retcode <> 0 or @@error <> 0
                return 1
        end
    END

    DELETE msdb..MSdistpublishers where UPPER(name) = UPPER(@publisher)
    IF @@ERROR <> 0  RETURN (1)


    declare @fExists int
    exec @fExists = dbo.sp_MSIfExistsRemoteLogin @publisher, 'distributor_admin', 'sa'
    if (@fExists = 1)
    BEGIN
       EXECUTE @retcode = dbo.sp_dropremotelogin @publisher, 'distributor_admin', sa
       IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1)
    END

    exec @fExists = dbo.sp_MSIfExistsRemoteLogin @publisher, 'distributor_admin', 
        'distributor_admin'
    if (@fExists = 1)
    BEGIN
       EXECUTE @retcode = dbo.sp_dropremotelogin @publisher, 'distributor_admin',
            'distributor_admin'
       IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1)
    END

/* SECURITY ********************************
    IF EXISTS (SELECT * FROM master..sysremotelogins
       WHERE remoteserverid = (SELECT srvid FROM master..sysservers
       WHERE UPPER(srvname) = UPPER(@publisher))
       AND remoteusername = 'sa'
       AND suid = 1)     --'sa' 
*********************************/


/* SECURITY ********************************
    IF EXISTS (SELECT * FROM master..sysremotelogins
       WHERE remoteserverid = (SELECT srvid FROM master..sysservers
       WHERE UPPER(srvname) = UPPER(@publisher))
       AND remoteusername = 'probe'
       AND suid = 10)     -- 'probe' 
    exec @fExists = dbo.sp_MSIfExistsRemoteLogin @publisher, 'probe', 'probe'
    if (@fExists = 1)
    BEGIN
       EXECUTE @retcode = dbo.sp_remoteoption @publisher, probe, probe, trusted, false
       IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1)
    END
*********************************/

    return(@return_status)
GO
 
raiserror('Creating procedure sp_adddistpublisher', 0,1)
go

CREATE PROCEDURE sp_adddistpublisher (
    @publisher sysname,      /* publisher server name */
    @distribution_db sysname,
    @security_mode int = NULL,
    @login sysname = 'sa',
    @password sysname = NULL,
    @working_directory nvarchar(255),
    @trusted nvarchar(5) = NULL,
    @encrypted_password bit = 0,
    @thirdparty_flag bit = 0
        ) AS

    SET NOCOUNT ON

    /*
    ** Declarations.
    */

    DECLARE @retcode int
    DECLARE @reg_key nvarchar(255)
    DECLARE @distbit int
    DECLARE @active_value int
    DECLARE @server_added bit
    DECLARE @proc nvarchar(255)
    declare @fExists int
    declare @command nvarchar(255)
    declare @trusted_id bit
    declare @platform_nt binary
	declare @qv_replication varchar(10)
	declare @qv_replication_unlimited integer
	declare @qv_value_replication integer

    select @platform_nt = 0x1
	select @qv_replication = '2745196162', @qv_replication_unlimited = 0

    SELECT @distbit = 16
    SELECT @server_added = 0

    /* 
    ** Check if replication components are installed on this server
    */
    exec @retcode = dbo.sp_MS_replication_installed
    if (@retcode <> 1)
    begin
        return (1)
    end

    IF @working_directory IS NULL or ltrim(rtrim(@working_directory)) = ' '
    BEGIN
        RAISERROR (14043, 16, -1, '@working_directory')
        GOTO UNDO
    END


    /*
    ** Parameter Check:  @publisher.
    ** Check to make sure that the publisher is not NULL and that it
    ** conforms to the rules for identifiers.
    */

    IF @publisher IS NULL
        BEGIN
            RAISERROR (14043, 16, -1, '@publisher')
            GOTO UNDO
        END

    EXECUTE @retcode = dbo.sp_validname @publisher

    IF @@ERROR <> 0 OR @retcode <> 0
        GOTO UNDO

	IF @password = N''
		select @password = [REDACTED]

    /* On REPLICATION_LIMITED server, only local publisher is supported.
     * Note: The login and password registered for local publisher will be used for 
     * local agents to login to distributor, thus local publisher has to be installed first.
     * We choose not to support remote dist publshers on REPLICATION_LIMITED server altogether.
     * On NT, local agents will always use integrated security to log into 
     * distributor
	 * Today, REPLICATION_LIMITED means desktop but we check specific sku entry just in case
	*/
	exec @qv_value_replication = master.dbo.xp_qv @qv_replication 	
    if ( @qv_value_replication != @qv_replication_unlimited ) and ( UPPER(@publisher) <> UPPER(@@servername) )
    begin
        -- remote dist publisher is not supported on this server version
        raiserror(21041,16,-1)
        goto UNDO
    end


    -- Set default security
    IF @security_mode IS NULL
    BEGIN
        IF (UPPER(@publisher) = UPPER(@@SERVERNAME) and ( platform() & @platform_nt = @platform_nt ) )
            SELECT @security_mode = 1
        ELSE
            SELECT @security_mode = 0
    END

    /* 
    ** Check for invalid security mode
    */
    IF @security_mode < 0 OR @security_mode > 1
        BEGIN
            RAISERROR(14109, 16, -1)
            GOTO UNDO
        END

    IF (UPPER(@publisher) = UPPER(@@SERVERNAME) and ( @platform_nt != platform() & @platform_nt ) and @security_mode = 1)
    BEGIN
        RAISERROR(21038, 16, -1)
        RETURN (1)
    END

    -- Encrypt the password
    IF @encrypted_password = 0
    BEGIN
        EXEC @retcode = master.dbo.xp_repl_encrypt @password OUTPUT
        IF @@error <> 0 OR @retcode <> 0
            return 1
    END

    -- Validate the working directory 
    -- Remove heading and trailing spaces
    select @working_directory = RTRIM(LTRIM(@working_directory))
    
    -- if the last char is '\', remove it.
    if substring(@working_directory, len(@working_directory),1) = '\'
        select @working_directory = substring(@working_directory, 1,
            len(@working_directory)-1)

    -- Don't do validation if it is a UNC path due to security problem.
    -- If the server is started as a service using local system account, we
    -- don't have access to the UNC path.
    if substring(@working_directory, 1,2) <> '\\'
    begin
        select @command = 'dir ' + @working_directory
        exec @retcode = master..xp_cmdshell @command, 'no_output'
        if @@error <> 0
            goto UNDO
        if @retcode <> 0 
        begin
            raiserror (21037, 16, -1, @working_directory)
            goto UNDO
        end
    end

    /*
    ** Parameter Check:  @trusted
    */

    if @trusted is null
    begin
        if UPPER(@publisher) = UPPER(@@servername)
            select @trusted = 'false'
        else
            select @trusted = 'true'
    end

    IF LOWER(@trusted) NOT IN ('true', 'false')
        BEGIN
            RAISERROR (14148, 16, -1, '@trusted')
            RETURN (1)
        END

    IF LOWER(@trusted) = 'true' SELECT @trusted_id = 1
    ELSE SELECT @trusted_id = 0

    /*
    ** Check to make sure this is a distributor
    */
    IF NOT EXISTS (SELECT * FROM master..sysservers
              WHERE UPPER(datasource) = UPPER(@@SERVERNAME)
                 AND srvstatus & 8 <> 0)
    BEGIN
        RAISERROR (14114, 16, -1, @@SERVERNAME)
        GOTO UNDO
    END

    /*
    ** Check if database is configured as a distributor database
    */
    IF NOT EXISTS (SELECT * FROM msdb..MSdistributiondbs WHERE name = @distribution_db)
    BEGIN
        RAISERROR (14117, 16, -1, @distribution_db)
        GOTO UNDO
    END

    /* Check if publisher is already defined. */
    IF EXISTS (SELECT *
         FROM msdb..MSdistpublishers
        WHERE UPPER(name) = UPPER(@publisher))

    BEGIN
        RAISERROR (14074, 16, -1, @publisher)
        RETURN (1)
    END



    IF NOT EXISTS (SELECT *
             FROM master..sysservers
            WHERE UPPER(srvname) = UPPER(@publisher))

    /* Add the server if it does not exist. */
    BEGIN
        EXECUTE @retcode = dbo.sp_addserver @publisher
        IF @@error <> 0 OR @retcode <> 0
        BEGIN
            RAISERROR (14075, 16, -1)
            GOTO UNDO
        END
        SELECT @server_added = 1
    END

     
    /*
    ** Set the Active  value.
    ** If the @publisher is local, set it to true.
    ** Otherwise, set it to false
    */
    IF UPPER(@publisher) = UPPER(@@SERVERNAME)
        SELECT @active_value = 1
    ELSE
        SELECT @active_value = 0


    DELETE msdb.dbo.MSdistpublishers where UPPER(name) = UPPER(@publisher)
    IF @@ERROR <> 0
    BEGIN
        GOTO UNDO       
    END

    INSERT INTO msdb.dbo.MSdistpublishers VALUES (
        @publisher, @distribution_db, @working_directory,
        @security_mode, @login, @password, @active_value, @trusted_id, @thirdparty_flag)
    IF @@ERROR <> 0
    BEGIN
        GOTO UNDO       
    END

    -- Add distributor_admin to distribution_admin non trusted mapping
    exec @fExists = dbo.sp_MSIfExistsRemoteLogin @publisher, null, 
        'distributor_admin'
    if( @fExists = 0 )
    BEGIN

        EXECUTE @retcode = dbo.sp_addremotelogin @publisher, 'distributor_admin', 
            'distributor_admin'
        IF @@error <> 0 OR @retcode <> 0
        BEGIN
            RAISERROR (14075, 16, -1)
            GOTO UNDO
        END
    END

    -- For 6x publisher, we still need the trusted sa to sa.
    -- For 6x publisher upgrading to 7.0, distributor_admin to distributor_admin need to be trusted.
    -- add remotelogin of SA if it doesn't already exist
    -- If there's a mapping for remote login sa already, we cannot map it to distributor_admin
    -- this is the case of server upgraded from 6.5.
    exec @fExists = dbo.sp_MSIfExistsRemoteLogin @publisher, null, 'sa'
    if( @fExists = 0 )
    BEGIN
        EXECUTE @retcode = dbo.sp_addremotelogin @publisher, 'distributor_admin', 'sa'
        IF @@error <> 0 OR @retcode <> 0
        BEGIN
            RAISERROR (14075, 16, -1)
            GOTO UNDO
        END
    END
    if @trusted_id = 1
    begin
        exec @fExists = dbo.sp_MSIfExistsRemoteLogin @publisher, 'distributor_admin', 'sa'
        if( @fExists = 1 )
        BEGIN
            EXECUTE @retcode = dbo.sp_remoteoption @publisher, 'distributor_admin', 'sa', trusted, true
            IF @@error <> 0 OR @retcode <> 0
            BEGIN
                RAISERROR (14075, 16, -1)
                GOTO UNDO
            END
        END

        EXECUTE @retcode = dbo.sp_remoteoption @publisher, 'distributor_admin', 'distributor_admin', trusted, true
        IF @@error <> 0 OR @retcode <> 0
        BEGIN
            RAISERROR (14075, 16, -1)
            GOTO UNDO
        END
    END


    /* Add remotelogin enabling the 'probe' of the publisher to
    ** RPC for distribution counter information.
    */
/* SECURITY ********************************
    IF NOT EXISTS (SELECT *
              FROM master..sysremotelogins srl,
               master..sysservers ss
             WHERE ss.srvname = @publisher
           AND srl.remoteserverid = ss.srvid
           AND srl.remoteusername = 'probe'
       AND srl.suid = 10)    -- 'probe' 
    exec @fExists = dbo.sp_MSIfExistsRemoteLogin @publisher, 'probe', 'probe'
    if (@fExists = 0)
    BEGIN
       EXECUTE @retcode = dbo.sp_addremotelogin @publisher, 'probe', 'probe'
       IF @@error <> 0 OR @retcode <> 0
       BEGIN
        RAISERROR (14075, 16, -1)
        GOTO UNDO
       END
    END
*********************************/
    
    RETURN(0)

UNDO:
    -- If the server is marked, drop it
    IF EXISTS (SELECT *
         FROM msdb..MSdistpublishers
        WHERE UPPER(name) = UPPER(@publisher))
        EXEC dbo.sp_dropdistpublisher @publisher

    IF @server_added = 1
        EXEC dbo.sp_dropserver @publisher

    RETURN(1)
GO
 

raiserror('Creating procedure sp_changedistpublisher', 0,1)
go

CREATE PROCEDURE sp_changedistpublisher (
    @publisher sysname,
    @property sysname     = NULL,     /* The property to change */
    @value nvarchar(255)     = NULL      /* The new property value */
    ) AS

    SET NOCOUNT ON

    /*
    ** Declarations.
    */
    DECLARE @retcode int
    DECLARE @new_database sysname
    DECLARE @new_security_mode int
    DECLARE @new_login sysname
    DECLARE @new_password sysname
    DECLARE @distbit int
    DECLARE @new_active int
    DECLARE @new_trusted bit
    DECLARE @command nvarchar(255)
    declare @distribdb sysname
    DECLARE @platform_nt binary

    SELECT @platform_nt = 0x1
    SELECT @distbit = 16
    
    /*
    ** Parameter Check:  @property.
    ** If the @property parameter is NULL, print the options.
    */

    IF @property IS NULL
        BEGIN
            CREATE TABLE #tab1 (properties sysname NOT NULL)
            INSERT INTO #tab1 VALUES ('distribution_db')
            INSERT INTO #tab1 VALUES ('working_directory')
            INSERT INTO #tab1 VALUES ('security_mode')
            INSERT INTO #tab1 VALUES ('login')
            INSERT INTO #tab1 VALUES ('password')
            INSERT INTO #tab1 VALUES ('active')
            INSERT INTO #tab1 VALUES ('trusted')
            SELECT * FROM #tab1
            RETURN (0)
        END

    /*
    ** Parameter Check:  @property.
    ** Check to make sure that @property is a valid property in
    ** sysarticles.
    */
    IF @property IS NULL OR LOWER(@property) NOT IN ('distribution_db',
         'working_directory',
         'security_mode',
         'login',
         'password',
         'active',
         'trusted')
        BEGIN
            RAISERROR (14115, 16, -1, 
            '''distribution_db'', ''working_directory'', ''security_mode'', ''login'', ''password'', ''active'', ''or trusted''')
            RETURN (1)
        END

    /*
    ** Check to make sure this is a distributor
    */
    IF NOT EXISTS (SELECT * FROM master..sysservers
              WHERE UPPER(datasource) = UPPER(@@SERVERNAME)
                 AND srvstatus & 8 <> 0)
    BEGIN
        RAISERROR (14114, 16, -1, @@SERVERNAME)
        RETURN(1)
    END

    -- Get the distribution db name.
    select @distribdb = distribution_db from msdb..MSdistpublishers where
        UPPER(name) = UPPER(@publisher)

    /*
    ** Change the property.
    */
    IF LOWER(@property) = 'distribution_db'
        BEGIN
            IF @value IS NULL
                BEGIN
                    RAISERROR (14043, 16, -1, '@value') 
                    RETURN (1)
                END

            IF @value <> @distribdb and 
                EXISTS (SELECT * FROM msdb.dbo.MSdistpublishers WHERE
                UPPER(name) = UPPER(@publisher) and active = 1)
            BEGIN
                RAISERROR (21046, 16, -1)
                RETURN (1)
            END

            /*
            ** Check if database is configured as a distributor database
            */
            IF NOT EXISTS (SELECT * FROM master..sysdatabases
              WHERE name = @value
                 AND category & @distbit <> 0)
                BEGIN
                    RAISERROR (14117, 16, -1, @new_database)
                    RETURN(1)
                END

            UPDATE msdb..MSdistpublishers SET distribution_db = @value
                WHERE UPPER(name) = UPPER(@publisher)
            IF @@error <> 0 
                BEGIN
                    RETURN (1)
                END
        END
   
    IF LOWER(@property) = 'working_directory'
        BEGIN
            IF @value IS NULL
                BEGIN
                    RAISERROR (14043, 16, -1, '@value') 
                    RETURN (1)
                END

            
            -- Validate the working directory 
            -- Remove heading and trailing spaces
            select @value = RTRIM(LTRIM(@value))

            -- if the last char is '\', remove it.

            if substring(@value, len(@value),1) = '\'
                select @value = substring(@value, 1,
                    len(@value)-1)

            -- Don't do validation if it is a UNC path due to security problem.
            -- If the server is started as a service using local system account, we
            -- don't have access to the UNC path.
            if substring(@value, 1,2) <> '\\'
            begin
                select @command = 'dir ' + @value
                exec @retcode = master..xp_cmdshell @command, 'no_output'
                if @@error <> 0
                    return 1
                if @retcode <> 0 
                begin
                    raiserror (21037, 16, -1, @value)
                    return 1
                end
            end

            UPDATE msdb..MSdistpublishers SET working_directory = @value
                WHERE UPPER(name) = UPPER(@publisher)
            IF @@error <> 0 
                BEGIN
                    RETURN (1)
                END
        END

    IF LOWER(@property) = 'security_mode'
        BEGIN
            IF @value IS NULL
                BEGIN
                    RAISERROR (14043, 16, -1, '@value') 
                    RETURN (1)
                END

            /*
            ** Set the SecurityMode registry key value
            */
            SELECT @new_security_mode = CONVERT(int, @value)

            /* 
            ** Check for invalid values 
            */
            IF @new_security_mode < 0 OR @new_security_mode > 1
                BEGIN
                    RAISERROR(14109, 16, -1)
                    RETURN (1)
                END

            IF (UPPER(@publisher) = UPPER(@@SERVERNAME) and ( @platform_nt != platform() & @platform_nt ) and @new_security_mode = 1)
            BEGIN
                RAISERROR(21038, 16, -1)
                RETURN (1)
            END

            UPDATE msdb..MSdistpublishers SET security_mode = @new_security_mode
                WHERE UPPER(name) = UPPER(@publisher)
            IF @@error <> 0 
                BEGIN
                    RETURN (1)
                END
        END

    IF LOWER(@property) = 'login'
        BEGIN
            IF @value IS NULL
                BEGIN
                    RAISERROR (14043, 16, -1, '@value') 
                    RETURN (1)
                END

            /*
            ** Set the Login registry key value
            */
            SELECT @new_login = CONVERT(sysname, @value)

            UPDATE msdb..MSdistpublishers SET login = @new_login
                WHERE UPPER(name) = UPPER(@publisher)
            IF @@error <> 0 
                BEGIN
                    RETURN (1)
                END
        END

    IF LOWER(@property) = 'password'
        BEGIN
            /*
            ** Set the Password registry key value
            */
            SELECT @new_password = [REDACTED] @value)

            -- Encrypt the password
            EXEC @retcode = master.dbo.xp_repl_encrypt @new_password OUTPUT
            IF @@error <> 0 OR @retcode <> 0
                RETURN (1)

            UPDATE msdb..MSdistpublishers SET password = [REDACTED]
                WHERE UPPER(name) = UPPER(@publisher)
            IF @@error <> 0 
                BEGIN
                    RETURN (1)
                END
         END

    IF LOWER(@property) = 'active'
        BEGIN
            /*
            ** Check for a valid  value.
            */

            IF LOWER(@value) NOT IN ('true', 'false')
            BEGIN
                RAISERROR (14137, 16, -1)
                RETURN (1)
            END

            IF LOWER(@value) = 'true'
            begin
                -- Clean up the database in case of the remote publisher is reinstalling publishing.
                SELECT @command = @distribdb + '.dbo.sp_MSdistpublisher_cleanup'
                exec @retcode = @command @publisher
                if @retcode <> 0 or @@error <> 0
                    return 1
                SELECT @new_active = 1
            end
            ELSE
            BEGIN
                SELECT @new_active = 0
            END

            /*
            ** Set the Active registry key value
            */
            UPDATE msdb..MSdistpublishers SET active = @new_active
                WHERE UPPER(name) = UPPER(@publisher)
            IF @@error <> 0
                BEGIN
                    RETURN (1)
                END

        END

    IF LOWER(@property) = 'trusted'
        BEGIN
            /*
            ** Check for a valid  value.
            */

            IF LOWER(@value) NOT IN ('true', 'false')
            BEGIN
                RAISERROR (14137, 16, -1)
                RETURN (1)
            END

            declare @fExists int

            IF LOWER(@value) = 'true'
            begin
                SELECT @new_trusted = 1
                exec @fExists = dbo.sp_MSIfExistsRemoteLogin @publisher, 'distributor_admin', 'sa'
                if( @fExists = 1 )
                BEGIN
                    EXECUTE @retcode = dbo.sp_remoteoption @publisher, 'distributor_admin', 'sa', trusted, true
                    IF @@error <> 0 OR @retcode <> 0
                    BEGIN
                        RAISERROR (14075, 16, -1)
                        RETURN (1)
                    END
                END


                EXECUTE @retcode = dbo.sp_remoteoption @publisher, 'distributor_admin', 
                    'distributor_admin', trusted, true
                IF @@error <> 0 OR @retcode <> 0
                BEGIN
                    RAISERROR (14075, 16, -1)
                    RETURN (1)
                END
            end
            ELSE
            BEGIN
                SELECT @new_trusted = 0
     
                exec @fExists = dbo.sp_MSIfExistsRemoteLogin @publisher, 'distributor_admin', 'sa'
                if( @fExists = 1 )
                BEGIN
                    EXECUTE @retcode = dbo.sp_remoteoption @publisher, 'distributor_admin', 'sa', trusted, false
                    IF @@error <> 0 OR @retcode <> 0
                    BEGIN
                        RAISERROR (14075, 16, -1)
                        RETURN (1)
                    END
                END


                EXECUTE @retcode = dbo.sp_remoteoption @publisher, 'distributor_admin',
                    'distributor_admin', trusted, 'false'
                IF @@error <> 0 OR @retcode <> 0
                BEGIN
                    RAISERROR (14075, 16, -1)
                    RETURN (1)
                END
            END

            /*
            ** Set the trusted registry key value
            */
            UPDATE msdb..MSdistpublishers SET trusted = @new_trusted
                WHERE UPPER(name) = UPPER(@publisher)
            IF @@error <> 0
                BEGIN
                    RETURN (1)
                END

        END
  
    /*
    ** Return succeed.
    */
    RAISERROR (21035, 10, -1, @property)

DONE:    
    RETURN (0)
go
 
raiserror('Creating procedure sp_helpdistpublisher', 0,1)
go

CREATE PROCEDURE sp_helpdistpublisher (
    @publisher sysname = '%'         /* publisher server name */
        ) AS

    SET NOCOUNT ON

    IF @publisher IS null
        begin
            raiserror (14043, 16, -1, '@publisher')
            return (1)
        end

    /*
    ** Check to make sure this is a distributor
    */
    IF NOT EXISTS (select * from master..sysservers
              where UPPER(datasource) = UPPER(@@SERVERNAME)
                 AND srvstatus & 8 <> 0)
    begin
		if @publisher <> '%' 
		begin
				raiserror (14114, 16, -1, @@SERVERNAME)
				return(1)
		end
		else
			return(0)
    end

    IF @publisher <> '%' AND NOT EXISTS (select * from msdb..MSdistpublishers
            where UPPER(name) = UPPER(@publisher))
    begin
        raiserror (14080, 11, -1)
        return (1)
    end

    SELECT name, distribution_db, security_mode, login,
		-- Not to return password unless sysadmin is called.
		'password' = [REDACTED]  when is_srvrolemember ('sysadmin') = 1 then password
			else convert(sysname, NULL)
		end,
		active, working_directory, trusted, thirdparty_flag
		FROM msdb.dbo.MSdistpublishers 
		where (@publisher = N'%') or (UPPER(name) = UPPER(@publisher))
	IF @@ERROR <> 0
    begin
        return(1)
    end
GO
 
dump tran master with no_log
go

raiserror('Creating procedure sp_add_agent_profile', 0,1)
go

/*
** The system profile of the same type of agent will be used as a template for 
** the parameters in this new user profile.
*/
CREATE PROCEDURE sp_add_agent_profile (
    @profile_id             int = 0 OUTPUT,
    @profile_name           sysname,
    @agent_type             int,            -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
    @profile_type           int = 0,        -- 0-System, 1-Custom 
    @description            nvarchar(3000),
    @default                bit = 0         -- 0-Not Default, 1-Default
)
AS
    SET NOCOUNT ON

    declare     @sys_profile    int
    declare     @default_id     int
    declare     @retcode        int

    SELECT @profile_name = RTRIM(@profile_name)

    IF @profile_name IS NULL
    BEGIN
        RAISERROR (14043, 16, -1, '@profile_name')
        RETURN (1)
    END

	exec @retcode = dbo.sp_MSreplcheck_name @profile_name
    if @@ERROR <> 0 or @retcode <> 0
        return(1)

    /* The profile name is unique across a particular agent type */
    IF EXISTS ( SELECT * FROM msdb..MSagent_profiles 
            WHERE profile_name = @profile_name
            AND agent_type = @agent_type )
    BEGIN
        RAISERROR(20057, 16, -1, @profile_name)
        RETURN (1)
    END

    IF @agent_type NOT IN (1, 2, 3, 4)
    BEGIN
        RAISERROR(20058, 16, -1)
        return (1)
    END

    IF @profile_type NOT IN (0, 1)
    BEGIN
        RAISERROR(20059, 16, -1)
        return (1)
    END

    BEGIN TRAN

    /*
    ** First find out the default profile of the same agent type
    */
    select @default_id = profile_id from msdb..MSagent_profiles WHERE agent_type = @agent_type AND def_profile = 1
    
    /* Only one profile for an agent type must be default */
    IF @default = 1
        UPDATE msdb..MSagent_profiles
            SET def_profile = 0 WHERE profile_id = @default_id
    IF @@ERROR <> 0
        GOTO UNDO
        
    INSERT INTO msdb..MSagent_profiles
            VALUES (@profile_name, @agent_type, @profile_type, @description, @default)
    IF @@ERROR <> 0
        GOTO UNDO

    IF @profile_id IS NULL
        SELECT @profile_id = profile_id 
        FROM msdb..MSagent_profiles
        WHERE profile_name = @profile_name 
        AND agent_type = @agent_type

	/*
	** If there is system profiles of the same agent type, use the primary system one as template of parameter set
	*/
	IF EXISTS (select * from msdb..MSagent_profiles where agent_type = @agent_type AND type = 0)
		select @default_id = min(profile_id) from msdb..MSagent_profiles where agent_type = @agent_type AND type = 0

	if @profile_type=1
	BEGIN
   	 	INSERT INTO msdb..MSagent_parameters 
    	    select @profile_id, parameter_name, value from msdb..MSagent_parameters 
        	    where profile_id = @default_id      
		if @@ERROR<>0 RETURN 1
	END

    COMMIT TRAN
    RETURN 0 

UNDO:
    IF @@TRANCOUNT = 1
        ROLLBACK TRAN
    ELSE
        COMMIT TRAN

    RETURN 1 
GO

raiserror('Creating procedure sp_drop_agent_parameter', 0,1)
go

-- Drop a/all parameter(s) of a/all profile(s) from the MSagent_parameters table
create procedure sp_drop_agent_parameter (
    @profile_id int,
    @parameter_name     sysname = '%'
)
as
    set nocount on

    declare @default            bit
    declare @agent_type         int
    declare @retstatus          int
    
    if @parameter_name is null
    BEGIN
        RAISERROR (14043, 16, -1, '@parameter_name')
        RETURN (1)
    END

    select @agent_type = agent_type, @default=def_profile
    from msdb..MSagent_profiles
    where profile_id = @profile_id

    if @default is null
    BEGIN
        RAISERROR (20066, 16, -1) -- profile not defined
        RETURN (1)
    END

    /* Delete the parameters of the profile */
    delete  msdb..MSagent_parameters 
    where   parameter_name like @parameter_name
    and     profile_id = @profile_id

    if @@error <> 0
    begin
        select @retstatus = 1
        goto UNDO
    end

    select @retstatus = 0

UNDO:
    
    return @retstatus
GO

raiserror('Creating procedure sp_drop_agent_profile', 0,1)
go
-- Drop a profile from the MSagent_profiles table, as well as the corresponding
-- parameters from the MSagent_parameters table

CREATE PROCEDURE sp_drop_agent_profile (
    @profile_id int
)
AS
    SET NOCOUNT ON

    declare @snapshot_type      int
    declare @logreader_type     int
    declare @distribution_type  int
    declare @merge_type         int
    
    declare @tablename          nvarchar(255)
    declare @proc               nvarchar(255)
    declare @distribution_db    sysname
    declare @profile_type       int

    declare @default            bit
    declare @usage_count        int
    declare @agent_type         int
    declare @retstatus          int
    DECLARE @retcode            int

    declare @default_sys_id     int

    SELECT @agent_type = agent_type, @profile_type = type, @default=def_profile
    FROM msdb..MSagent_profiles
    WHERE profile_id = @profile_id

    IF @default IS NULL
    BEGIN
        RAISERROR (20066, 16, -1) -- Profile not defined
        RETURN (1)
    END

    /*
    ** Before dropping a default profile, one system profile of the same agent type
    ** has to become the new default profile.
    */
    IF @default = 1
    BEGIN
        select @default_sys_id=min(profile_id) from msdb..MSagent_profiles
            where agent_type = @agent_type AND type = 0
            
        UPDATE msdb..MSagent_profiles SET def_profile = 1 WHERE profile_id = @default_sys_id
    END

    select @snapshot_type = 1
    select @logreader_type = 2
    select @distribution_type = 3
    select @merge_type = 4

        /* By default, assume that this profile is not being used */
    select @usage_count = -1

    select @tablename = 
        case @agent_type
            when @snapshot_type then 'MSsnapshot_agents'
            when @logreader_type then 'MSlogreader_agents'
            when @distribution_type then 'MSdistribution_agents'
            when @merge_type then 'MSmerge_agents'
        end

    declare hCdistdbs CURSOR LOCAL FAST_FORWARD FOR
        select distinct distribution_db 
        from msdb..MSdistpublishers
        for read only

    open hCdistdbs
    fetch hCdistdbs into @distribution_db

    while @@fetch_status <> -1 and @usage_count = -1
    begin
        select @proc = @distribution_db + '.dbo.sp_MSprofile_in_use'
        execute @usage_count = @proc @tablename = @tablename, @profile_id = @profile_id
    
        if @@error <> 0
        begin
            select @retstatus = 1
            goto UNDO
        end

        fetch hCdistdbs into @distribution_db
    end

    /* A profile in use cannot be dropped */
    if @usage_count = 0 
    begin
        RAISERROR(20065, 16, -1) -- Cannot drop profile, because it is in use.
        select @retstatus = 1
        goto UNDO 
    end

    BEGIN TRAN

    /*****
     * NOTE : If sp_drop_agent_parameter fails, the profile must not be 
     * deleted either 
     */
    EXECUTE @retcode = dbo.sp_drop_agent_parameter @profile_id = @profile_id,
                            @parameter_name = '%'

    IF @@ERROR <> 0 OR @retcode <> 0
        GOTO UNDO
            
    /* Delete all the entries in one go */
    DELETE msdb..MSagent_profiles 
    WHERE profile_id = @profile_id

    IF @@ERROR <> 0
        GOTO UNDO

    COMMIT TRAN

    close hCdistdbs
    deallocate hCdistdbs

    RETURN 0

UNDO:
    IF @@TRANCOUNT = 1
        ROLLBACK TRAN
    ELSE IF @@TRANCOUNT > 1 -- Sometimes we can get here when @@trancount = 0, so need to check explicitly.
        COMMIT TRAN

    close hCdistdbs
    deallocate hCdistdbs


    RETURN (1)
GO

raiserror('Creating procedure sp_help_agent_profile', 0,1)
go


-- View the row(s) of the MSagent_profiles table

create procedure sp_help_agent_profile(
    @agent_type     int = 0,
    @profile_id int = -1
)
as
    set nocount on

    declare @proc nvarchar(255)

    declare @snapshot_type      int
    declare @logreader_type     int
    declare @distribution_type  int
    declare @merge_type     int

    select @snapshot_type = 1
    select @logreader_type = 2
    select @distribution_type = 3
    select @merge_type = 4

    if @agent_type is null 
    BEGIN
        RAISERROR (14043, 16, -1, '@agent_type')
        RETURN (1)
    END

    if @profile_id is null
    BEGIN
        RAISERROR (14043, 16, -1, '@profile_id')
        RETURN (1)
    END

    if @agent_type not in (0, @snapshot_type, @logreader_type, @distribution_type, @merge_type)
    BEGIN
        RAISERROR(20058, 16, -1)
        return (1)
    END


    select @proc =  ' select profile_id, profile_name, agent_type, type, ' +
            ' description, def_profile ' +
            ' from msdb..MSagent_profiles ' +
            case 
              when @profile_id <> -1 then ' where profile_id = ' + convert(nvarchar(10),@profile_id) else ' '
            end

    if @agent_type <> 0 
        if @profile_id = -1
            select @proc = @proc + ' where '
        else 
            select @proc = @proc + ' and '

    select @proc = @proc + 
            case 
              when @agent_type <> 0 then ' agent_type = ' + convert(nvarchar(10),@agent_type) else ' '
            end
    
    select @proc = @proc + ' order by profile_id, profile_name'

    execute (@proc)
GO

raiserror('Creating procedure sp_help_agent_default', 0,1)
go

create procedure sp_help_agent_default (
    @profile_id     int OUTPUT, 
    @agent_type         int
)
as
    set nocount on

    if @agent_type not in (1, 2, 3, 4)
    BEGIN
        RAISERROR(20058, 16, -1)
        return (1)
    END


    select @profile_id = profile_id 
    from msdb..MSagent_profiles 
    where agent_type = @agent_type
    and def_profile = 1 
go

raiserror('Creating procedure sp_MSupdate_agenttype_default', 0,1)
go

-- Set a profile as a default for an agent_type
create procedure sp_MSupdate_agenttype_default(
    @profile_id int
)
as
    set nocount on

    declare @agent_type int

    /* This profile must have been defined for this agent type */
    if not exists ( select * from msdb..MSagent_profiles
            where profile_id = @profile_id )
    BEGIN
        RAISERROR (20066, 16, -1)   -- profile not defined
        RETURN (1)
    END


    select @agent_type = agent_type
    from msdb..MSagent_profiles 
    where profile_id = @profile_id

    BEGIN TRAN

    update msdb..MSagent_profiles
    set def_profile = 0
    where agent_type = @agent_type
    and def_profile = 1

    if @@error <> 0
        goto UNDO

    update msdb..MSagent_profiles
    set def_profile = 1
    where profile_id = @profile_id

    if @@error <> 0
        goto UNDO 

    COMMIT TRAN

    return 0

UNDO:
    if @@trancount = 1
        rollback tran
    else
        commit tran

    return 1 
GO


/*
** Create stored procedures to generate default profile 
** parameters for replication agents.
*/

raiserror('Creating procedure sp_generate_agent_parameter', 0,1)
GO

create procedure sp_generate_agent_parameter(
	@profile_id     int
)
as
    declare @retcode    int

	 
    /* 
	** Snapshot agent 
	*/
	if (@profile_id = 1)
	  begin
		exec @retcode = dbo.sp_add_agent_parameter 
			    @profile_id = @profile_id,
				@parameter_name = '-BcpBatchSize',
				@parameter_value = '100000'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-HistoryVerboseLevel',
				@parameter_value = '2'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-LoginTimeout',
				@parameter_value = '15'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-MaxBcpThreads',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-QueryTimeout',
				@parameter_value = '300'        -- 5 minutes 
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

	  end

    /* 
	** Logreader agent 
	*/
	else if (@profile_id = 2)
	  begin
  
		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-HistoryVerboseLevel',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-LoginTimeout',
				@parameter_value = '15'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-PollingInterval',
				@parameter_value = '10'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-QueryTimeout',
				@parameter_value = '300'        -- 5 minutes
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-ReadBatchSize',
				@parameter_value = '500'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-ReadBatchThreshold',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

	  end

    /* 
	** Logreader agent - Verbose History Profile
	*/
	else if (@profile_id = 3)
	  begin

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-HistoryVerboseLevel',
				@parameter_value = '2'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-LoginTimeout',
				@parameter_value = '15'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-PollingInterval',
				@parameter_value = '10'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-QueryTimeout',
				@parameter_value = '300'        -- 5 minutes
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-ReadBatchSize',
				@parameter_value = '500'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-ReadBatchThreshold',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE
	  end

    /* 
	** Distribution agent 
	*/
	else if (@profile_id = 4)
	  begin

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-BcpBatchSize',
				@parameter_value = '100000'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-CommitBatchSize',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-CommitBatchThreshold',
				@parameter_value = '1000'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-HistoryVerboseLevel',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-LoginTimeout',
				@parameter_value = '15'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-MaxBcpThreads',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-MaxDeliveredTransactions',
				@parameter_value = '0'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-PollingInterval',
				@parameter_value = '10'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-QueryTimeout',
				@parameter_value = '300'        -- 5 minutes 
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-SkipFailureLevel',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-TransactionsPerHistory',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

	  end

    /*
	** Distribution Agent Verbose History Profile
	*/
	else if (@profile_id = 5)
	  begin

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-BcpBatchSize',
				@parameter_value = '100000'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-CommitBatchSize',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-CommitBatchThreshold',
				@parameter_value = '1000'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-HistoryVerboseLevel',
				@parameter_value = '2'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-LoginTimeout',
				@parameter_value = '15'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-MaxBcpThreads',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-MaxDeliveredTransactions',
				@parameter_value = '0'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-PollingInterval',
				@parameter_value = '10'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-QueryTimeout',
				@parameter_value = '300'        -- 5 minutes 
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-SkipFailureLevel',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-TransactionsPerHistory',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

	  end
    /* 
	** Merge agent : Default profile for well connected scenarios 
	*/
	else if (@profile_id = 6)
	  begin

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-PollingInterval',
				@parameter_value = '60'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-ValidateInterval',
				@parameter_value = '60'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-LoginTimeout',
				@parameter_value = '15'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-QueryTimeout',
				@parameter_value = '300'        
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-UploadGenerationsPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-DownloadGenerationsPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-UploadReadChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-DownloadReadChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-UploadWriteChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-DownloadWriteChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-Validate',
				@parameter_value = '0'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-FastRowCount',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE
        
		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-HistoryVerboseLevel',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-ChangesPerHistory',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE
		exec @retcode = dbo.sp_add_agent_parameter 
			    @profile_id = @profile_id,
				@parameter_name = '-BcpBatchSize',
				@parameter_value = '100000'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE
			
	  end

    /* 
	** Merge agent : Non default profile for disconnected scenarios ( unreliable link ) 
	*/
	else if (@profile_id = 7)
	  begin

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-PollingInterval',
				@parameter_value = '60'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-ValidateInterval',
				@parameter_value = '60'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-LoginTimeout',
				@parameter_value = '15'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-QueryTimeout',
				@parameter_value = '300'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-UploadGenerationsPerBatch',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-DownloadGenerationsPerBatch',
				@parameter_value = '20'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-UploadReadChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-DownloadReadChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-UploadWriteChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-DownloadWriteChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-Validate',
				@parameter_value = '0'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE
        
		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-HistoryVerboseLevel',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-ChangesPerHistory',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE
		exec @retcode = dbo.sp_add_agent_parameter 
			    @profile_id = @profile_id,
				@parameter_name = '-BcpBatchSize',
				@parameter_value = '100000'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE
	  end

    /* 
	** Merge agent : Default profile for well connected scenarios - Verbose history logging 
	*/
	else if (@profile_id = 8)
	  begin

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-PollingInterval',
				@parameter_value = '60'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-ValidateInterval',
				@parameter_value = '60'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-LoginTimeout',
				@parameter_value = '15'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-QueryTimeout',
				@parameter_value = '300'        
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-UploadGenerationsPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-DownloadGenerationsPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-UploadReadChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-DownloadReadChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-UploadWriteChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-DownloadWriteChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-Validate',
				@parameter_value = '0'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-FastRowCount',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE
        
		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-HistoryVerboseLevel',
				@parameter_value = '3'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-ChangesPerHistory',
				@parameter_value = '50'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE
		exec @retcode = dbo.sp_add_agent_parameter 
			    @profile_id = @profile_id,
				@parameter_name = '-BcpBatchSize',
				@parameter_value = '100000'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE
	  end

    /* 
	** Merge agent : (Synchronization Manager Profile)
	*/
	else if (@profile_id = 9)
	  begin

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-PollingInterval',
				@parameter_value = '60'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-ValidateInterval',
				@parameter_value = '60'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-LoginTimeout',
				@parameter_value = '15'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-QueryTimeout',
				@parameter_value = '300'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-UploadGenerationsPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-DownloadGenerationsPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-UploadReadChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-DownloadReadChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-UploadWriteChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-DownloadWriteChangesPerBatch',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-Validate',
				@parameter_value = '0'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE
        
		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-HistoryVerboseLevel',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-ChangesPerHistory',
				@parameter_value = '50'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE
		exec @retcode = dbo.sp_add_agent_parameter 
			    @profile_id = @profile_id,
				@parameter_name = '-BcpBatchSize',
				@parameter_value = '1000'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE
	  end

    /* 
	** Distribution agent (Synchronization Manager Profile)
	*/
	else if (@profile_id = 10)
	  begin

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-BcpBatchSize',
				@parameter_value = '1000'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-CommitBatchSize',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-CommitBatchThreshold',
				@parameter_value = '1000'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-HistoryVerboseLevel',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-LoginTimeout',
				@parameter_value = '15'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-MaxBcpThreads',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-MaxDeliveredTransactions',
				@parameter_value = '0'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-PollingInterval',
				@parameter_value = '10'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-QueryTimeout',
				@parameter_value = '300'        -- 5 minutes 
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-SkipFailureLevel',
				@parameter_value = '1'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

		exec @retcode = dbo.sp_add_agent_parameter 
				@profile_id = @profile_id,
				@parameter_name = '-TransactionsPerHistory',
				@parameter_value = '100'
		if (@retcode = 1 or @@ERROR <> 0)
			goto FAILURE

	  end
	
    return 0
FAILURE:
    return 1
go

dump tran msdb with no_log
GO

raiserror('Creating procedure sp_MSvalidate_agent_parameter', 0,1)
go
create procedure sp_MSvalidate_agent_parameter (
    @profile_id      int,
    @parameter_name  sysname,
    @parameter_value nvarchar(255)
)
as
    declare @agent_type  int
    declare @original_parameter_name sysname
    declare @numeric_value int

    -- Make sure parameters are non-null
    if @profile_id is null
    BEGIN
        RAISERROR (14043, 16, -1, '@profile_id')
        RETURN (1)
    END

    if @parameter_name is null 
    BEGIN
        RAISERROR (14043, 16, -1, '@parameter_name')
        RETURN (1)
    END

    IF @parameter_value is null
    BEGIN
        RAISERROR (14043, 16, -1, '@parameter_value')
        RETURN (1)
    END

    select @original_parameter_name = @parameter_name
    
    select @agent_type = agent_type
    from msdb..MSagent_profiles 
    where profile_id = @profile_id

    -- Parameter name validation
    if (substring(@parameter_name, 1, 1) <> '/' and 
        substring(@parameter_name, 1, 1) <> '-')
    begin
        return 1
    end

    select @parameter_name = lower(substring(@parameter_name, 2, len(@parameter_name) - 1))

    -- Snapshot agent - agent_type = 1
    if (@agent_type = 1)
    begin
        if not @parameter_name in ( 
            N'bcpbatchsize',   
            N'historyverboselevel',
            N'logintimeout',
            N'maxbcpthreads',
            N'querytimeout'
            )    
        begin
            raiserror(21111, 16, -1, @original_parameter_name)
            return 1
        end
    end
    -- Logreader - agent_type = 2
    else if (@agent_type =2)  
    begin
        if not lower(@parameter_name) in ( 
            N'historyverboselevel',
            N'logintimeout',
            N'pollinginterval',
            N'querytimeout',
            N'readbatchsize',
            N'readbatchthreshold'
            )    
        begin
            raiserror(21112, 16, -1, @original_parameter_name)
            return 1
        end
    end
    -- Distribution agent - agent_type = 3
    else if (@agent_type = 3)
    begin
        if not @parameter_name in ( 
            N'bcpbatchsize',   
            N'commitbatchsize',   
            N'commitbatchthreshold',   
            N'historyverboselevel',
            N'logintimeout',
            N'maxbcpthreads',
            N'maxdeliveredtransactions',
            N'pollinginterval',
            N'querytimeout',
            N'skipfailurelevel',
            N'transactionsperhistory'
            )    
        begin
            raiserror(21113, 16, -1, @original_parameter_name)
            return 1
        end
    end
    -- Merge agent - agent_type = 4
    else if (@agent_type = 4)
    begin 
        if not @parameter_name in ( 
            N'pollinginterval',   
            N'validateinterval',   
            N'logintimeout',   
            N'querytimeout',   
            N'uploadgenerationsperbatch',   
            N'downloadgenerationsperbatch',   
            N'uploadreadchangesperbatch',   
            N'downloadreadchangesperbatch',   
            N'uploadwritechangesperbatch',
            N'downloadwritechangesperbatch',
            N'validate',   
            N'fastrowcount',   
            N'historyverboselevel',
            N'changesperhistory',
            N'bcpbatchsize'
            )    
        begin
            raiserror(21114, 16, -1, @original_parameter_name)
            return 1
        end
    end
    else if @agent_type is null
    begin
        raiserror (20066, 16, -1)   -- profile not defined
        return 1
    end
    else
    begin
        -- MSagent_parameters table corruption
        return 1
    end

    -- Parameter value validation
    if (@parameter_name = N'bcpbatchsize')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end
    end
    else if (@parameter_name = N'commitbatchsize')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'commitbatchthreshold')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'downloadgenerationsperbatch')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'downloadreadchangesperbatch')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'downloadwritechangesperbatch')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'fastrowcount')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or not (@numeric_value in (1,2,3))
        begin
            raiserror(21116, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'historyverboselevel')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or not (@numeric_value in (0,1,2,3))
        begin
            raiserror(21117, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'logintimeout')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'maxbcpthreads')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'maxdeliveredtransactions')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 0
        begin
            raiserror(21119, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'pollinginterval')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'querytimeout')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'readbatchsize')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'readbatchthreshold')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'skipfailurelevel')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 0 
        begin
            raiserror(21119, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'transactionsperhistory')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value not between 0 and 10000
        begin
            raiserror(211118, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'uploadgenerationsperbatch')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'uploadreadchangesperbatch')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'uploadwritechangesperbatch')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'validate')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or not (@numeric_value in (0,1,2))
        begin
            raiserror(21117, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end
    else if (@parameter_name = N'validateinterval')
    begin
        select @numeric_value = convert(int, @parameter_value)
        if @@error <> 0 or @numeric_value < 1
        begin
            raiserror(21115, 16, -1, @parameter_value, @original_parameter_name)
            return 1     
        end                        
    end

    return 0
go 

EXEC dbo.sp_MS_marksystemobject 'sp_MSvalidate_agent_parameter'


raiserror('Creating procedure sp_add_agent_parameter', 0,1)
go

-- Add a row into the "MSagent_parameters" table
create procedure sp_add_agent_parameter (
    @profile_id int,
    @parameter_name         sysname,
    @parameter_value        nvarchar(255)
)
as
    declare @slash_parameter_name sysname
    declare @dash_parameter_name sysname
    declare @retcode int
    
    set nocount on

    select @parameter_name = RTRIM(@parameter_name)


    -- Call proc to validate parameter value
    exec @retcode = dbo.sp_MSvalidate_agent_parameter 
                        @profile_id = @profile_id, 
                        @parameter_name = @parameter_name,
                        @parameter_value = @parameter_value
    if @retcode <> 0
        RETURN(1)


    select @slash_parameter_name = lower(stuff(@parameter_name, 1, 1, N'/'))
    select @dash_parameter_name = lower(stuff(@parameter_name, 1, 1, N'-'))
     

    /* A parameter may be defined only once per profile */
    if exists ( select * from msdb..MSagent_parameters 
            where profile_id = @profile_id
            and (@slash_parameter_name = lower(parameter_name) 
            or @dash_parameter_name = lower(parameter_name)))
    BEGIN
        RAISERROR (20067, 16, -1, @parameter_name)  -- The parameter name ''%s'' already exists for the specified profile
        RETURN (1)
    END

    insert into msdb..MSagent_parameters
    values (@profile_id, @parameter_name, @parameter_value) ;

    if @@error <> 0
        return(1)
GO

raiserror('Creating procedure sp_change_agent_parameter', 0,1)
go
-- Change one parameter of a profile from the MSagent_parameters table
create procedure sp_change_agent_parameter(
    @profile_id int,
    @parameter_name         sysname,
    @parameter_value        nvarchar(255)
)AS
    declare @slash_parameter_name sysname
    declare @dash_parameter_name sysname
    declare @retcode int

    select @parameter_name = RTRIM(@parameter_name)

    -- Call proc to validate parameter value
    exec @retcode = dbo.sp_MSvalidate_agent_parameter 
                        @profile_id = @profile_id, 
                        @parameter_name = @parameter_name,
                        @parameter_value = @parameter_value
    if @retcode <> 0
        RETURN(1)


    select @slash_parameter_name = lower(stuff(@parameter_name, 1, 1, N'/'))
    select @dash_parameter_name = lower(stuff(@parameter_name, 1, 1, N'-'))
   
    IF exists ( select * from msdb..MSagent_parameters 
            where profile_id = @profile_id and 
                (@slash_parameter_name = lower(parameter_name) or
                 @dash_parameter_name = lower(parameter_name)))
    BEGIN
        update msdb..MSagent_parameters set value = @parameter_value where 
            profile_id = @profile_id and 
            (@slash_parameter_name = lower(parameter_name) or
            @dash_parameter_name = lower(parameter_name)) 

        if @@error <> 0
            return(1)
    END
GO

raiserror('Creating procedure sp_change_agent_profile', 0,1)
go
-- Change one parameter of a profile from the MSagent_profiles table
create procedure sp_change_agent_profile(
    @profile_id         int,
    @property           sysname,
    @value              nvarchar(3000)
)AS

    IF lower(@property) not in ('description')
    BEGIN
        RAISERROR('the @property parameter must be ''description''. ', 16, -1)
        RETURN (1)
    END

    IF exists ( select * from msdb..MSagent_profiles where profile_id = @profile_id)
    BEGIN
        update msdb..MSagent_profiles set description = @value where profile_id = @profile_id
        if @@error <> 0
            return(1)
    END
GO


raiserror('Creating procedure sp_help_agent_parameter', 0,1)
go
-- View all the parameters of a profile from the MSagent_parameters table
create procedure sp_help_agent_parameter(
    @profile_id     int = -1
)
as
    set nocount on
    
    if @profile_id = -1
    begin   
        select profile_id, parameter_name, value
        from msdb..MSagent_parameters
        order by profile_id, parameter_name
    end
    else
    begin
        select profile_id, parameter_name, value
        from msdb..MSagent_parameters
        where profile_id = @profile_id
        order by profile_id, parameter_name
    end
GO

raiserror('Creating procedure sp_MShelp_distdb', 0,1)
go

-- Called by the distribution agent to find the dist. db of a dist. publisher
create procedure sp_MShelp_distdb (     
    @publisher_name     sysname
)
as
if exists (select name from msdb..sysobjects where name = 'MSdistpublishers')
begin
    select distribution_db from msdb..MSdistpublishers
    where UPPER(name) = UPPER(@publisher_name)
end
else 
    select NULL where 1=2   /* We still want an empty rowset for some agents */
GO

dump tran master with no_log
GO

raiserror('Creating procedure sp_MSupdate_replication_status', 0,1)
go
create procedure sp_MSupdate_replication_status
@publisher sysname,
@publisher_db sysname,
@publication sysname,
@publication_type int = 0,      -- 0 Transactional/Snapshot 1 Merge
@agent_type int,
@agent_name nvarchar(100),
@status int
as

    declare @deleted int
    declare @refresh int
	declare @getstatus int

    set @deleted = -1
    set @refresh = -2			-- Status used to only update the timestamp column
	set @getstatus = -3			-- Get status of agent for dummy distribution row

    if (select object_id('tempdb.dbo.MSreplication_agent_status')) is NULL
        return 0

	if @status = @getstatus
	begin
		select @status = isnull(status, 0) from tempdb.dbo.MSreplication_agent_status where
			UPPER(publisher) = UPPER(@publisher) and
            publisher_db = @publisher_db and
            publication = 'ALL' and
			agent_type = @agent_type
	end			

	-- Update timestamp column via dummy update
	if @status = @refresh
	begin
		-- Dummy update to force timestamps to be updated.
        update tempdb.dbo.MSreplication_agent_status set status = status where
            UPPER(publisher) = UPPER(@publisher) and
            publisher_db = @publisher_db and
            publication like @publication -- Must use like as publication may be "%"
        return (0)
	end

    -- Remove row if @deleted
    if @status = @deleted
    begin
        if @agent_name = '%'
            delete from tempdb.dbo.MSreplication_agent_status where
                UPPER(publisher) = UPPER(@publisher) and
                publisher_db = @publisher_db and
                publication = @publication and
                agent_type = @agent_type 
		else if @agent_name = NULL	-- Special case when all agents of the type are dropped
		    delete from tempdb.dbo.MSreplication_agent_status where
                UPPER(publisher) = UPPER(@publisher) and
                publisher_db = @publisher_db and
                publication = @publication and
				agent_type = @agent_type
        else
            delete from tempdb.dbo.MSreplication_agent_status where
                UPPER(publisher) = UPPER(@publisher) and
                publisher_db = @publisher_db and
                publication = @publication and
                agent_type = @agent_type and
                agent_name = @agent_name

        -- Dummy update to force timestamps to be updated.  This will signal a row has been
        -- removed.
        update tempdb.dbo.MSreplication_agent_status set status = status where
            UPPER(publisher) = UPPER(@publisher) and
            publisher_db = @publisher_db and
            publication = @publication
        return (0)
    end     

    -- If misc. replication job then the status needs to be mapped.
    if @agent_type = 5
    begin
        set @status = 
        case isnull(@status,5)	-- mapped to never run
            when 0 then 6   -- Fail mapping
            when 1 then 2   -- Success mapping
            when 2 then 5   -- Retry mapping
            when 3 then 2   -- Shutdown mapping
            when 4 then 3   -- Inprogress mapping
            when 5 then 0   -- Unknown is mapped to never run
        end
    end

    if not exists (select * from tempdb.dbo.MSreplication_agent_status where 
        UPPER(publisher) = UPPER(@publisher) and
        publisher_db = @publisher_db and
        publication = @publication and
        agent_type = @agent_type and
        agent_name = @agent_name)
        begin
            insert into tempdb.dbo.MSreplication_agent_status 
                (publisher, publisher_db, publication, publication_type, agent_type, status, agent_name) values
                (@publisher, @publisher_db, @publication, @publication_type, @agent_type, @status, @agent_name)
            -- Dummy update to force timestamps to be updated.  This will signal a row has been
            -- added.
            update tempdb.dbo.MSreplication_agent_status set status = status where
                UPPER(publisher) = UPPER(@publisher) and
                publisher_db = @publisher_db and
                publication = @publication
        end
    else
        begin
            update tempdb.dbo.MSreplication_agent_status set status = @status where
                UPPER(publisher) = UPPER(@publisher) and
                publisher_db = @publisher_db and
                (publication = @publication or @publication = 'ALL')and
                agent_type = @agent_type and
                agent_name = @agent_name
        end                 

    return (0)
go

raiserror('Creating procedure sp_MSenum_misc_agents', 0,1)
go
create procedure sp_MSenum_misc_agents
as
    SET NOCOUNT ON

    declare @timestamp timestamp

    -- Not supported, but returned to be consistent with other sp_MSenum_replication_agent
    -- result set.
    set @timestamp = 0

    select j.name, 'agent_type' = c.name,
            'status' = case isnull(jh.run_status, 5) -- mapped to never run
                when 0 then 6   -- Fail mapping
                when 1 then 2   -- Success mapping
                when 2 then 5   -- Retry mapping
                when 3 then 2   -- Shutdown mapping
                when 4 then 3   -- Inprogress mapping
                when 5 then 0   -- Unknown is mapped to never run
            end,
            jh.message, 'start_time' = convert(nvarchar(8), jh.run_date) + N' ' +
                                       stuff(stuff(right(convert(nvarchar(7), jh.run_time + 1000000), 6), 5, 0, N':'), 3, 0, N':') + 
                                       + N'.000',
            jh.run_duration, 
            'job_id' = convert(binary(16), j.job_id), 'local_timestamp' = @timestamp from 
                msdb..sysjobs j
            LEFT OUTER JOIN msdb..sysjobhistory jh ON
            j.job_id = jh.job_id and 
            jh.step_id = 1 and
            jh.instance_id = (select max(instance_id) from msdb..sysjobhistory jh2 where
                jh2.job_id = j.job_id and jh2.step_id = 1)
            INNER JOIN msdb..syscategories c ON
            j.category_id = c.category_id
            where j.category_id in (11, 12,16,17,18)

    order by j.job_id asc
go 

raiserror('Creating procedure sp_MSload_replication_status', 0,1)
go

create proc sp_MSload_replication_status
as
    set nocount on

    declare @db_name sysname
    declare @distbit int
    declare @retcode int

    select @distbit = 16
    select @retcode = 0

    -- Create the table if it does not exist
    if (select object_id('tempdb.dbo.MSreplication_agent_status')) is NULL
    begin
        exec @retcode = dbo.sp_MScreate_replication_status_table
        if @@error <> 0 or @retcode <> 0
            return 1
    end
    else
        -- Flush out all current rows
        truncate table tempdb.dbo.MSreplication_agent_status

    -- Load misc. replication jobs status and map SQL Agent status to replication status
    insert into tempdb.dbo.MSreplication_agent_status 
        select '', '', '', -1, 5, 
            case isnull(jh.run_status,5) -- mapped to never run
                when 0 then 6   -- Fail mapping
                when 1 then 2   -- Success mapping
                when 2 then 5   -- Retry mapping
                when 3 then 2   -- Shutdown mapping
                when 4 then 3   -- Inprogress mapping
                when 5 then 0   -- Unknown is mapped to never run
            end,
            j.name, NULL from msdb..sysjobs j
            LEFT OUTER JOIN msdb..sysjobhistory jh ON
            j.job_id = jh.job_id and 
            jh.instance_id = (select max(instance_id) from msdb..sysjobhistory jh2 where
                jh2.job_id = j.job_id)
            where j.category_id in (11,12,16,17,18)
    if @@error <> 0
        return 1

    declare hCdatabase CURSOR LOCAL FAST_FORWARD FOR
        select name from master.dbo.sysdatabases 
            where
            category & @distbit <> 0 and
            (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0)
        for read only

    open hCdatabase
    fetch next from hCdatabase into @db_name
    while (@@fetch_status <> -1)
    begin

        insert into tempdb.dbo.MSreplication_agent_status 
            (publisher, publisher_db, publication, publication_type, agent_type, status, agent_name)
            exec (@db_name + '.dbo.sp_MSenum_replication_status')

        fetch next from hCdatabase into @db_name
    end
        
DONE:
    close hCdatabase
    deallocate hCdatabase


    -- Add and initialize Perfmon SQL Replication Agents instances
    exec @retcode = dbo.sp_MSinit_replication_perfmon
    if @retcode <> 0 or @@error <> 0
        return 1

GO

raiserror('Creating procedure sp_MScreate_replication_status_table', 0,1)
go
create proc sp_MScreate_replication_status_table
as
    declare @retcode int

    if (select object_id('tempdb.dbo.MSreplication_agent_status')) is NULL
    begin
        -- begin tran
        create table tempdb.dbo.MSreplication_agent_status (
            publisher sysname NOT NULL,
            publisher_db sysname NOT NULL,
            publication sysname NOT NULL,
            publication_type int NOT NULL,          -- 0 transactional/snapshot  1 Merge
            agent_type int NOT NULL,
            status int NOT NULL,
            agent_name nvarchar(100) NOT NULL,
            timestamp NOT NULL,
            CONSTRAINT pk_MSrepl PRIMARY KEY (timestamp, agent_type)
            )
        if @@error <> 0
            return 1
        
        create nonclustered index uncMSreplication_agent_status ON 
            tempdb.dbo.MSreplication_agent_status (status, publisher, publisher_db, publication, agent_type)
        
        if @@error <> 0
            return 1
    end
    return 0  -- If here, all is well and we're done.
go

raiserror('Creating procedure sp_MShelp_replication_status', 0,1)
go

create procedure sp_MShelp_replication_status
@publisher sysname = '%',
@publisher_db sysname = '%',
@publication sysname = '%',
@agent_type int = 0
as
    declare @retcode int
    declare @max_status int
    declare @max_timestamp timestamp
    declare @publication_type int
    declare @all_status int
    declare @all_timestamp timestamp


    -- If the temporary status table does not exist, create it and populate it.
    if (select object_id('tempdb.dbo.MSreplication_agent_status')) is NULL
    begin                                           
        exec @retcode = dbo.sp_MSload_replication_status
        if @@error <> 0
            return 1
    end


    -- @agent_type is only supported with all wildcards
    if @agent_type <> 0 and (@publisher <> '%' or @publisher_db <> '%' or @publication <> '%')
        return 1
    
    if @publisher = '%'
    begin
        -- @agent_type = 0 returns status of all agents including the misc. agents.
        -- @agent_type = -1 returns status of all agents except misc. agents.
        if @agent_type = 0 or @agent_type = -1
        begin
            select @max_status = max(status) from tempdb.dbo.MSreplication_agent_status (NOLOCK)
                where (@agent_type = -1 and agent_type <> 5) or
                      @agent_type = 0
            select @max_timestamp = max(timestamp) from tempdb.dbo.MSreplication_agent_status (NOLOCK)
                where (@agent_type = -1 and agent_type <> 5) or
                      @agent_type = 0
        end
        else
        begin
            select @max_status = max(status) from tempdb.dbo.MSreplication_agent_status (NOLOCK) where
                agent_type = @agent_type
            select @max_timestamp = max(timestamp) from tempdb.dbo.MSreplication_agent_status (NOLOCK) where
                agent_type = @agent_type
        end
    end
    else if @publication = '%'
    begin
        select @max_status = max(status) from tempdb.dbo.MSreplication_agent_status (NOLOCK) where
            UPPER(publisher) = UPPER(@publisher) 
--          publisher_db = @publisher_db 
        select @max_timestamp = max(timestamp) from tempdb.dbo.MSreplication_agent_status (NOLOCK) where
            UPPER(publisher) = UPPER(@publisher) 
--          publisher_db = @publisher_db 
    end
    else if @publication <> '%'
    begin
        select top 1 @max_status = status from tempdb.dbo.MSreplication_agent_status (NOLOCK) where
            UPPER(publisher) = UPPER(@publisher) and
            publisher_db = @publisher_db and
            publication = @publication
            order by status desc
        
		-- Get publication type from the Snapshot agent of the Publication. This used to determine
		-- if the Logreader status should be included.
		select @publication_type = publication_type from tempdb.dbo.MSreplication_agent_status (NOLOCK) where
            UPPER(publisher) = UPPER(@publisher) and
            publisher_db = @publisher_db and
            publication = @publication and
            agent_type = 1	-- Snapshot agent

        select @max_timestamp = max(timestamp) from tempdb.dbo.MSreplication_agent_status (NOLOCK) where
            UPPER(publisher) = UPPER(@publisher) and
            publisher_db = @publisher_db and
            publication = @publication 

        -- If publication_type = 0 then transactional and must include the Logreader
		-- with publication = 'ALL'
        if @publication_type = 0
        begin
            select @all_status = status, @all_timestamp = timestamp from tempdb.dbo.MSreplication_agent_status (NOLOCK) where
                UPPER(publisher) = UPPER(@publisher) and
                publisher_db = @publisher_db and
				publication = 'ALL' and
				agent_type = 2 --Logreader

            if @all_status > @max_status
                set @max_status = @all_status

            if @all_timestamp > @max_timestamp
                set @max_timestamp = @all_timestamp
        end

    end

    -- Return result set
    select 'status' = isnull(@max_status, 0), 'timestamp' = isnull (@max_timestamp, 0)

    return (0)
go

raiserror('Creating procedure sp_MSenum_replication_agents', 0,1)
go
create procedure sp_MSenum_replication_agents
@type int
as
    set nocount on

    declare @snapshot int
    declare @logreader int
    declare @distribution int
    declare @sproc sysname
    declare @db_name sysname
    declare @table_name sysname
    declare @cmd nvarchar(255)
    declare @distbit int
    declare @merge int
    declare @misc int

    select @distbit = 16

    select @snapshot = 1
    select @logreader = 2
    select @distribution = 3
    select @merge = 4
    select @misc = 5

    if @type = @misc
    begin
        exec dbo.sp_MSenum_misc_agents
        return 0
    end

    if @type = @snapshot
    begin
        select @sproc = 'sp_MSenum_snapshot'
        create table #snapshot (dbname sysname NOT NULL, name nvarchar(100) NOT NULL, 
            status int NOT NULL,
            publisher sysname NOT NULL, publisher_db sysname NOT NULL, 
            publication sysname NOT NULL,
            start_time nvarchar(24) NULL, time nvarchar(24) NULL, duration int NULL,
            comments nvarchar(255) NULL, delivered_transactions int NULL, 
            delivered_commands int NULL, delivery_rate float NULL, error_id INT NULL,
            job_id binary(16) NULL, local_job bit NULL, profile_id int NOT NULL, 
            agent_id int NOT NULL, local_timestamp binary(8) NOT NULL)

        create unique clustered index ucsnapshot ON #snapshot (job_id)

        select @table_name = '#snapshot'
    end
    else if @type = @logreader
    begin
        select @sproc = 'sp_MSenum_logreader'
        create table #logreader (dbname sysname NOT NULL, name nvarchar(100) NOT NULL,  
            status int NOT NULL,
            publisher sysname NOT NULL, publisher_db sysname NOT NULL,
            start_time nvarchar(24) NULL, time nvarchar(24) NULL, duration int NULL,
            comments nvarchar(255) NULL, delivery_time int NULL, 
            delivered_transactions int NULL, delivered_commands int NULL, 
            average_commands int NULL, delivery_rate int NULL, delivery_latency int NULL, 
            error_id INT NULL, job_id binary(16) NULL, local_job bit NULL,
            profile_id int NOT NULL, agent_id int NOT NULL, local_timestamp binary(8) NOT NULL)

        create unique clustered index uclogreader ON #logreader (job_id)

        select @table_name = '#logreader'
    end
    else if @type = @distribution
    begin
        select @sproc = 'sp_MSenum_distribution'
        create table #distribution (dbname sysname NOT NULL, 
            name nvarchar(100) NOT NULL,  
            status int NOT NULL,
            publisher sysname NOT NULL, publisher_db sysname NOT NULL, 
            publication sysname NULL,
            subscriber sysname NULL, subscriber_db sysname NULL, subscription_type int NULL,
            start_time nvarchar(24) NULL, time nvarchar(24) NULL, duration int NULL,
            comments nvarchar(255) NULL, delivery_time int NULL, 
            delivered_transactions int NULL, delivered_commands int NULL, 
            average_commands int NULL, delivery_rate int NULL, 
            delivery_latency int NULL, error_id INT NULL,
            job_id binary(16) NULL, local_job bit NULL, profile_id int NOT NULL, 
            agent_id int NOT NULL, local_timestamp binary(8) NOT NULL)

	    create unique clustered index ucdistribution ON #distribution (job_id)

        select @table_name = '#distribution'
    end
    else if @type = @merge
    begin
        select @sproc = 'sp_MSenum_merge'
        create table #merge (dbname sysname NOT NULL, name nvarchar(100) NOT NULL, 
            status int NOT NULL,
            publisher sysname NOT NULL, publisher_db sysname NOT NULL, publication sysname NULL,
            subscriber sysname NULL, subscriber_db sysname NULL, subscription_type int NULL,
            start_time nvarchar(24) NULL, time nvarchar(24) NULL, duration int NULL, 
            comments nvarchar(255) NULL, delivery_rate int NULL,
            publisher_insertcount int NULL, publisher_updatecount int NULL, publisher_deletecount int NULL,
            publisher_conficts int NULL, 
            subscriber_insertcount int NULL, subscriber_updatecount int NULL, subscriber_deletecount int NULL,
            subscriber_conficts int NULL, error_id int NULL, job_id binary(16) NULL,
            local_job bit NULL, profile_id int NOT NULL, agent_id int NOT NULL, local_timestamp binary(8) NOT NULL)

		create unique clustered index ucmerge ON #merge (job_id)


        select @table_name = '#merge'
    end

    declare hCdatabase CURSOR LOCAL FAST_FORWARD FOR
        select name from master.dbo.sysdatabases 
            where
            category & @distbit <> 0 and
            (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0)
        for read only

    open hCdatabase
    fetch next from hCdatabase into @db_name
    while (@@fetch_status <> -1)
    begin
        select @cmd = 'insert into ' + @table_name +
            ' exec ' + @db_name + '.dbo.' + @sproc + ' @show_distdb = 1'
        exec (@cmd)
        fetch next from hCdatabase into @db_name
    end
    close hCdatabase
    deallocate hCdatabase

    select @cmd = 'select * from ' + @table_name + ' order by job_id asc'
    exec (@cmd)

    -- Drop the table
    select @cmd = 'drop table ' + @table_name
    exec (@cmd)

GO

raiserror('Creating procedure sp_replication_agent_checkup', 0,1)
go
create procedure sp_replication_agent_checkup
@heartbeat_interval int = 10        -- minutes
as
    declare @distribution_db sysname
    declare @retstatus int
    declare @proc nvarchar(255)
    declare @retcode int

    declare hCdistdbs CURSOR LOCAL FAST_FORWARD for
        select name from msdb..MSdistributiondbs where 
        (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0)    
    for read only
    open hCdistdbs
    fetch hCdistdbs into @distribution_db
    while @@fetch_status <> -1
    begin
        select @proc = @distribution_db + '.dbo.sp_MSagent_stethoscope'
        execute  @retcode = @proc @heartbeat_interval
        if @@error <> 0 or @retcode <> 0
        begin
            select @retstatus = 1
            goto UNDO
        end
        fetch hCdistdbs into @distribution_db
    end

    set @retstatus = 0

UNDO:
    close hCdistdbs
    deallocate hCdistdbs
    return (@retstatus)
go

raiserror('Creating procedure sp_MScreate_replication_checkup_agent', 0,1)
go
create procedure sp_MScreate_replication_checkup_agent
@heartbeat_interval int = 10    -- minutes
as
    declare @command nvarchar(100)
    declare @retcode int
    declare @interval int
    declare @job_name nvarchar(100)
    declare @description nvarchar(100)
    declare @category_name sysname

    select @command = 'sp_replication_agent_checkup @heartbeat_interval = ' +
        convert(nvarchar(10), @heartbeat_interval)      
        
    -- Create job if it already exists
    select @job_name = formatmessage(20533)

    IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @job_name and
        originating_server = '(local)')
    BEGIN
        EXEC @retcode = msdb.dbo.sp_delete_job  @job_name = @job_name
        IF @@ERROR <> 0 or @retcode <> 0
        BEGIN
            return (1)            
        END
    END

    -- Create new job
    set @interval = convert(int, @heartbeat_interval)
    set @description = formatmessage(20534)

    -- Get Checkup category name (assumes category_id = 16)
    select @category_name = name FROM msdb.dbo.syscategories where category_id = 16
    EXECUTE @retcode = dbo.sp_MSadd_repl_job 
            @name = @job_name,
            @subsystem = 'TSQL', 
            @enabled = 1, 
            @command = @command,
            @description = @description,
            @freqtype = 4,
            @freqinterval = 1,
            @freqsubtype = 4,
            @freqsubinterval = @interval,
            @retryattempts = 0,
            @category_name = @category_name
    if @@ERROR <> 0 or @retcode <> 0
        return (1)
go

raiserror('Creating procedure sp_MSenum_replication_job', 0,1)
go
create procedure sp_MSenum_replication_job
@job_id uniqueidentifier
as
    SET NOCOUNT ON
    declare @message nvarchar(1024)
    declare @retcode int
    declare @runstatus int
    declare @date int
    declare @time int

    -- Get last message from SQL Agent History table
    create table #JobHistory (
        instance_id int NOT NULL, 
        job_id uniqueidentifier NOT NULL,
        job_name nvarchar(100) NOT NULL,
        step_id int NOT NULL,
        step_name nvarchar(100) NOT NULL, 
        sql_message_id int NOT NULL,
        sql_severity int NOT NULL,
        message nvarchar(1024) NULL,
        run_status int NOT NULL,
        run_date int NOT NULL,
        run_time int NOT NULL,
        run_duration int NOT NULL,
        operator_emailed sysname NULL,
        operator_netsent sysname NULL,
        operator_paged sysname NULL,
        retries_attempted int NOT NULL,
        server sysname NOT NULL
    )
    if @@error <> 0
        return 1

    -- Insert last history for step_id 1 (Agent running)
    set rowcount 1
    insert into #JobHistory exec msdb.dbo.sp_help_jobhistory @job_id = @job_id, @step_id = 1, 
        @mode = 'FULL'          

    -- Get the last history
    select @message = message, @runstatus = run_status, @date = run_date, @time = run_time
        from #JobHistory

    -- Reset rowcount
    set rowcount 0

    -- Map SQL Agent runstatus to Replication runstatus
    set @runstatus = 
    case @runstatus
        when 0 then 6   -- Fail mapping
        when 1 then 2   -- Success mapping
        when 2 then 5   -- Retry mapping
        when 3 then 2   -- Shutdown mapping
        when 4 then 3   -- Inprogress mapping
        when 5 then 0   -- Unknown is mapped to never run
    end

    -- Return status and message
    select 'runstatus' = isnull(@runstatus, 0), 'message' = @message,  'date' = @date, 
        'time' = @time

    drop table #JobHistory
go 

raiserror('Creating procedure sp_MSrepl_dbrole', 0,1)
go
CREATE PROCEDURE sp_MSrepl_dbrole
    @rolename       sysname,
    @loginname      sysname,
    @operation      nvarchar(10),
    @is_member      bit = 0 OUTPUT
AS
    -- This is an internal stored procedure. 
    -- If operation is 'add', it will add the login as a user to current database if necessary
    -- get the user name of the login and add it to the role
    -- If operation is 'drop', it will drop the user from the role.
    -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES --
    declare @retcode int
    declare @username sysname
    declare @sid varbinary(85)

    select @sid = suser_sid(@loginname)

    if @operation = 'is_member'
    begin
        if exists (select * from sysusers r, sysusers u, sysmembers m where 
            u.sid = @sid and
            r.name = @rolename and
            m.groupuid = r.uid and
            m.memberuid = u.uid)
            select @is_member = 1
        else
            select @is_member = 0
        return(0)
    end
    
    -- Add the login to  db  role.
    if  is_srvrolemember('sysadmin',  @loginname) <> 1
    begin
        select @username = name from sysusers where sid = @sid
        if @operation = 'add'
        begin
            if @username is null
            begin
                -- Add the server login to be a user with same name in the database
                exec @retcode = dbo.sp_adduser  @loginname
                if @retcode<>0 or @@error <> 0
                    return 1
                select @username = @loginname
            end

            exec @retcode = dbo.sp_addrolemember @rolename, @username
            if @@error <> 0 OR @retcode <> 0
                return 1
        end
        else if @operation = 'drop'
        begin
            if @username is not null
            begin
                exec @retcode = dbo.sp_droprolemember @rolename, @username
                if @@error <> 0 OR @retcode <> 0
                    return 1
            end
        end
    end     
go

raiserror('Creating procedure sp_changedistributor_password', 0,1)
go
CREATE PROCEDURE sp_changedistributor_password (
    @password sysname       
    ) AS

    declare @distributor sysname
    declare @distnetname sysname
    declare @retcode int
    declare @login sysname

    select @login = 'distributor_admin'
    SELECT @distributor = NULL
    SELECT @distributor = srvname, @distnetname = datasource 
        FROM master..sysservers
        WHERE  srvstatus & 8 <> 0
    
    exec @retcode = dbo.sp_addlinkedsrvlogin 
        @rmtsrvname= @distributor,
        @useself = 'false',
        @locallogin = NULL,
        @rmtuser = @login,
        @rmtpassword = [REDACTED]
    IF @@error <> 0 OR @retcode <> 0
    BEGIN
        RETURN (1)
    END

    if UPPER(@distnetname) = UPPER(@@servername)
    begin
            -- Change the password if the distributor is local
        EXEC @retcode = dbo.sp_password NULL, @password, 'distributor_admin'
        if @@error <> 0 or @retcode <> 0
            return(1)
    end

    return (0)
GO

raiserror('Creating procedure sp_oledbinfo', 0,1)
go
CREATE PROCEDURE sp_oledbinfo
    @server nvarchar(128),
    @infotype nvarchar(128) = NULL,
    @login nvarchar(128) = NULL,
    @password nvarchar(128) = NULL
    AS

    SET NOCOUNT ON

    DECLARE @distributor sysname
    DECLARE @distproc nvarchar (255)
    DECLARE @retcode int

    /*
    ** Get distribution server information for remote RPC
    ** subscription calls.
    */

    EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT
    IF @@error <> 0 OR @retcode <> 0
        BEGIN
        RAISERROR (14071, 16, -1)
            RETURN (1)
    END

    select @distproc = rtrim(@distributor) + '.master.dbo.sp_MSget_oledbinfo'
    exec @retcode = @distproc @server, @infotype, @login, @password
    IF @@error <> 0
        BEGIN
        RAISERROR (14071, 16, -1)
        RETURN (1)
    END

go

raiserror('Creating procedure sp_MSget_oledbinfo', 0,1)
go
CREATE PROCEDURE sp_MSget_oledbinfo
    @server nvarchar(128),  -- the name by which the oledb datasource is referred to.
    @infotype nvarchar(128) = NULL,
    @login nvarchar(128) = NULL,
    @password nvarchar(128) = NULL
    AS

    SET NOCOUNT ON

    DECLARE @distproc nvarchar (255)
    DECLARE @providername nvarchar(255)
    DECLARE @datasource nvarchar(255)
    DECLARE @location nvarchar(255)
    DECLARE @providerstring nvarchar(255)
    DECLARE @catalog nvarchar(255)
    DECLARE @retcode int

    select @providername = providername, @datasource = datasource, @location = location, @providerstring = providerstring, @catalog = catalog
        from master..sysservers where UPPER(srvname) = UPPER(@server)

    if (@@rowcount = 0)
    begin
        raiserror(15015, 16, -1, @server)
        return (1)
    end

    exec @retcode = master..xp_oledbinfo @providername, @datasource, @location, @providerstring, @catalog, @login, @password, @infotype
    IF @@error <> 0
        BEGIN
        RAISERROR (14071, 16, -1)
        RETURN (1)
    END

go

raiserror('Creating procedure sp_grant_publication_access', 0,1)
go
CREATE PROCEDURE sp_grant_publication_access (
    @publication sysname,
    @login sysname,
    @reserved nvarchar(10) = NULL
        ) AS

    -- This stored procedure can be called repeatedly.
    DECLARE @distribdb sysname
    DECLARE @distproc nvarchar (255)
    DECLARE @retcode int
    DECLARE @dist_rpcname sysname
    DECLARE @database sysname
    
    -- Security Check
    exec @retcode = dbo.sp_MSreplcheck_publish
    if @@ERROR <> 0 or @retcode <> 0
        return(1)
	
	select @database = db_name()

	-- Existance check of the publication will be done in sp_MSpublication_access
    -- Note, even if the login exists, it may or may not has access
    -- to the server (granted or denied). 
    if @reserved is null
	begin
		if not exists (select * from master..syslogins where 
			sid = suser_sid(@login) and
			hasaccess = 1)
		begin
			raiserror(15007, 16, -1, @login) 
			return (1)
		end
		
        -- Don't do the user check if sysadmin since sysadmin can enter
        -- the database as dbo.
		if is_srvrolemember('sysadmin') = 0 and
            not exists (select * from sysusers where
			(sid = suser_sid(@login) or name = N'guest') and
			hasdbaccess = 1) 
		begin
			declare @login_len int
			declare @db_len int
			select @login_len = datalength(@login)
			select @db_len = datalength(@database)
			raiserror(916, 16, -1, @login_len, @login, 
				@db_len,@database) 
			return (1)			
		end
	end

    select @database = db_name()

    EXEC @retcode = dbo.sp_helpdistributor  @rpcsrvname = @dist_rpcname OUTPUT,
                                        @distribdb   = @distribdb   OUTPUT
    IF @@error <> 0
    BEGIN
         RAISERROR (14071, 16, -1)
         return (1)
    END

    IF @retcode <> 0 OR @distribdb IS NULL OR @dist_rpcname IS NULL
    BEGIN
        RAISERROR (14071, 16, -1)
        return(1)
    END

    SELECT @distproc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSpublication_access'
    
    declare @skip bit

    declare @login2 sysname

    if @reserved = 'init'
    begin
		-- Skip logins that are not at the distributor without
		-- raiseing error.
        set @skip = 1
        declare hC CURSOR LOCAL FAST_FORWARD for
            select loginname from master..syslogins where
                (is_srvrolemember('sysadmin', loginname) = 1 or
				sid = suser_sid()) 
		for read only
    end
    else
    begin
        set @skip = 0
        declare hC CURSOR LOCAL FAST_FORWARD for
                select @login
            for read only
    end

    open hC
    fetch hC into @login2

    while (@@fetch_status <> -1)
    begin
        EXEC @retcode = @distproc
             @publisher = @@SERVERNAME,
             @publisher_db = @database,
             @publication = @publication,
             @login= @login2,
             @operation = 'add',
             @skip = @skip
        IF @@error <> 0 OR @retcode <> 0
            return (1)

        fetch hC into @login2
    end
    
    close hC
    deallocate hC
GO

raiserror('Creating procedure sp_revoke_publication_access', 0,1)
go
CREATE PROCEDURE sp_revoke_publication_access (
    @publication sysname,
    @login sysname
        ) AS

    -- This stored procedure can be called repeatedly.
    DECLARE @distribdb sysname
    DECLARE @distproc nvarchar (255)
    DECLARE @retcode int
    DECLARE @dist_rpcname sysname
    DECLARE @database sysname

    -- Security Check
    exec @retcode = dbo.sp_MSreplcheck_publish
    if @@ERROR <> 0 or @retcode <> 0
        return(1)

    -- Do check existense when dropping since the login might be dropped
    -- outside replication already.

    select @database = db_name()

    EXEC @retcode = dbo.sp_helpdistributor  @rpcsrvname = @dist_rpcname OUTPUT,
                                        @distribdb   = @distribdb   OUTPUT
    IF @@error <> 0
    BEGIN
         RAISERROR (14071, 16, -1)
         return (1)
    END

    IF @retcode <> 0 OR @distribdb IS NULL OR @dist_rpcname IS NULL
    BEGIN
        RAISERROR (14071, 16, -1)
        return(1)
    END

    SELECT @distproc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSpublication_access'
    EXEC @retcode = @distproc
         @publisher = @@SERVERNAME,
         @publisher_db = @database,
         @publication = @publication,
         @login= @login,
         @operation = 'drop'

    IF @@error <> 0 OR @retcode <> 0
        return (1)
GO

raiserror('Creating procedure sp_help_publication_access', 0,1)
go
CREATE PROCEDURE sp_help_publication_access (
    @publication sysname,
    @return_granted bit = 1,
    @login sysname = '%',
	@initial_list bit = 0
        ) AS

    set nocount on
    -- This stored procedure can be called repeatedly.
    DECLARE @distribdb sysname
    DECLARE @distproc nvarchar (255)
    DECLARE @retcode int
    DECLARE @dist_rpcname sysname
    DECLARE @database sysname

    exec @retcode = dbo.sp_MSreplcheck_publish
    if @@ERROR <> 0 or @retcode <> 0
        return(1)

    -- Do check existense when dropping since the login might be dropped
    -- outside replication already.

    select @database = db_name()

    EXEC @retcode = dbo.sp_helpdistributor  @rpcsrvname = @dist_rpcname OUTPUT,
                                        @distribdb   = @distribdb   OUTPUT
    IF @@error <> 0
    BEGIN
         RAISERROR (14071, 16, -1)
         return (1)
    END

    IF @retcode <> 0 OR @distribdb IS NULL OR @dist_rpcname IS NULL
    BEGIN
        RAISERROR (14071, 16, -1)
        return(1)
    END

	SELECT @distproc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSpublication_access'

    -- Get logins in the PAL if needed
	if @initial_list = 0
	begin
		create table #granted (login sysname NULL)    
		insert into #granted EXEC @retcode = @distproc
			 @publisher = @@SERVERNAME,
			 @publisher_db = @database,
			 @publication = @publication,
			 @operation = 'help',
			 @login = @login

		IF @@error <> 0 OR @retcode <> 0
			return (1)
	end

	-- Get distributor valid logins if needed
	if @return_granted = 0 or @initial_list = 1
	begin
		create table #dist_logins(login sysname NULL)
		insert into #dist_logins EXEC @retcode = @distproc
			 @publisher = @@SERVERNAME,
			 @operation = 'get_logins'
	end

	if @initial_list = 1
	begin
		-- Get the initial list for the publication to be created
		-- by the current user
		-- It contains all the logins sysadmin group and the current user
		-- that have valid login at the distributor.
		select l.loginname, l.isntname, l.isntgroup
		 from master..syslogins l, #dist_logins d where
			l.sid = suser_sid(d.login) and
			l.hasaccess = 1 and
			(is_srvrolemember('sysadmin',d.login) = 1 or (l.sid = suser_sid())) 
	end
	else if @return_granted = 0
	begin
		select l.loginname, l.isntname, l.isntgroup
		 from master..syslogins l, #dist_logins d where
			l.sid = suser_sid(d.login) and
			l.hasaccess = 1 and 
			not exists (select * from #granted g where 
				suser_sid(g.login) = l.sid) and
			exists (select * from sysusers u where
				(u.sid = l.sid or u.name = 'guest') and
				u.hasdbaccess = 1)
	end
	else if @return_granted = 1
	begin
		select l.loginname, l.isntname, l.isntgroup from master..syslogins l,
			#granted g where
			l.sid = suser_sid(g.login)
	end
GO

raiserror('Creating procedure sp_check_publication_access', 0,1)
go
CREATE PROCEDURE sp_check_publication_access
@publication sysname
AS
    declare @retcode int
    exec @retcode = dbo.sp_MSreplcheck_pull 
        @publication = @publication
	if @retcode <> 0 or @@error <> 0
		return (1)
    return 0
GO

exec dbo.sp_MS_marksystemobject sp_check_publication_access
go

raiserror('Creating procedure sp_MSinit_replication_perfmon', 0,1)
go

create proc sp_MSinit_replication_perfmon
as
    declare @agent_type int
    declare @agent_name nvarchar(100)
    declare @status int

    -- Remove all existing instances
    dbcc deleteinstance ("SQL Replication Agents", "%")
    dbcc deleteinstance ("SQL Replication Snapshot", "%")
    dbcc deleteinstance ("SQL Replication Logreader", "%")
    dbcc deleteinstance ("SQL Replication Distribution", "%")
    dbcc deleteinstance ("SQL Replication Merge", "%")

    -- Add and initialize Perfmon SQL Replication Agents instances
    dbcc addinstance ("SQL Replication Agents", "Snapshot")
    dbcc addinstance ("SQL Replication Agents", "Logreader")
    dbcc addinstance ("SQL Replication Agents", "Distribution")
    dbcc addinstance ("SQL Replication Agents", "Merge")
    dbcc setinstance ("SQL Replication Agents", "Running", "Snapshot", 0)
    dbcc setinstance ("SQL Replication Agents", "Running", "Logreader", 0)
    dbcc setinstance ("SQL Replication Agents", "Running", "Distribution", 0)
    dbcc setinstance ("SQL Replication Agents", "Running", "Merge", 0)

    -- Add instances for each agent currently in the status table
    declare hC CURSOR LOCAL FAST_FORWARD for select agent_type, agent_name, status from tempdb.dbo.MSreplication_agent_status for read only
    open hC
    fetch hC into @agent_type, @agent_name, @status
    while (@@fetch_status <> -1)
    begin

        if @agent_type = 1 
        begin
            dbcc addinstance ("SQL Replication Snapshot", @agent_name)
            if @status = 1 or @status = 3 or @status = 4
                dbcc incrementinstance ("SQL Replication Agents", "Running", "Snapshot", 1)
        end
        else if @agent_type = 2 
        begin
            dbcc addinstance ("SQL Replication Logreader", @agent_name)
            if @status = 1 or @status = 3 or @status = 4
                dbcc incrementinstance ("SQL Replication Agents", "Running", "Logreader", 1)
        end
        else if @agent_type = 3 
        begin
            dbcc addinstance ("SQL Replication Distribution", @agent_name)
            if @status = 1 or @status = 3 or @status = 4
                dbcc incrementinstance ("SQL Replication Agents", "Running", "Distribution", 1)
        end
        else if @agent_type = 4 
        begin
            dbcc addinstance ("SQL Replication Merge", @agent_name)
            if @status = 1 or @status = 3 or @status = 4
                dbcc incrementinstance ("SQL Replication Agents", "Running", "Merge", 1)
        end

        fetch hC into @agent_type, @agent_name, @status
    end
    close hC
    deallocate hC
GO

raiserror('Creating procedure sp_MSrepl_startup', 0,1)
go
create proc sp_MSrepl_startup
as

    -- Drop and create publisher side cache table
    if exists (select * from tempdb..sysobjects where name = 'MSpublisher_access' and
    type = 'U')
        drop table tempdb.dbo.MSpublisher_access

    create table tempdb.dbo.MSpublisher_access
    (
    spid int NOT NULL,
    db_id int not null,
    publication sysname not null,
    login_time datetime not null,
    pubid uniqueidentifier null -- Used for merge only.
    )

    CREATE CLUSTERED INDEX ucMSpublisher_access ON tempdb.dbo.MSpublisher_access
        (spid, publication, db_id)

    -- Drop and create distributor side cache table
    -- We need to avoid publisher and distributor using the same table to prevent
    -- contention in local distributor case.
    if exists (select * from master..sysservers
                  WHERE  srvstatus & 8 <> 0 and UPPER(datasource) = UPPER(@@servername))
    begin
        if exists (select * from tempdb..sysobjects where name = 'MSdistributor_access' and
        type = 'U')
            drop table tempdb.dbo.MSdistributor_access

        create table tempdb.dbo.MSdistributor_access
        (
        spid int NOT NULL,
        db_id int not null,
        agent_id int not null,
        agent_type int not null,
        publication_id int not null,
        login_time datetime not null
        )

        CREATE CLUSTERED INDEX ucMSdistributor_access ON tempdb.dbo.MSdistributor_access
            (spid, agent_id, db_id)
    end
go

-- If a distributor is installed, mark the sp as a startup sp. 
if exists (select * FROM master..sysservers WHERE  srvstatus & 8 <> 0)
    exec dbo.sp_procoption 'sp_MSrepl_startup', 'startup', 'true' 
go

raiserror('Creating procedure sp_MSflush_access_cache', 0,1)
go
CREATE PROCEDURE sp_MSflush_access_cache 
AS
    -- Delete all the 'dead' connections in MSpublisher_access.
    delete tempdb.dbo.MSpublisher_access 
        from tempdb.dbo.MSpublisher_access a
        where not exists (select * from master..sysprocesses p where
            a.spid = p.spid and
            p.login_time = a.login_time)
    if @@error <> 0
        return 1
    else
        return 0

    if exists (select * from tempdb..sysobjects where name = 'MSdistributor_access' and
    type = 'U')
    begin
        -- Delete all the 'dead' connections in MSdistributor_access.
        delete tempdb.dbo.MSdistributor_access 
            from tempdb.dbo.MSdistributor_access a
            where not exists (select * from master..sysprocesses p where
                a.spid = p.spid and
                p.login_time = a.login_time)
        if @@error <> 0
            return 1
        else
            return 0
    end
    return (0)
GO

raiserror('Creating procedure sp_MSreinit_failed_subscriptions', 0,1)
go
-- This stored procedure is used as a response to the Replication Validation Failure Alert.
-- It will reinit the failed subscription. If the publisher is remote, it must be configured as a remote server 
-- for this procedure to work.
create proc sp_MSreinit_failed_subscriptions
@failure_level int = 0      -- 0 All failure  1 Validation failures
as

    declare @publisher sysname
    declare @publisher_db sysname
    declare @publication sysname
    declare @article sysname
    declare @publication_type int
    declare @subscriber sysname
    declare @subscriber_db sysname
    declare @agent_type int
    declare @alert_id int
    declare @proc nvarchar(100)
    declare @message nvarchar(4000)
    declare @retcode int
    declare @found bit
    declare @return_value int
    
    set nocount on

    set @found = 0          -- set if cursor returns a row
    set @return_value = 0   -- set to success

    -- For each publication validation failure, resync the subscription
    declare hc CURSOR LOCAL FAST_FORWARD for select publisher, publisher_db, publication, publication_type, article, subscriber, 
        subscriber_db, alert_id from 
        msdb..sysreplicationalerts where
        (@failure_level = 0 or (@failure_level = 1 and alert_error_code = 20574)) and   -- 20574 = validation failure
        status = 0
        for read only

    open hc
    fetch hc into  @publisher, @publisher_db, @publication, @publication_type, @article, @subscriber, @subscriber_db, @alert_id
    while (@@fetch_status <> -1)
    begin
        
        set @found = 1

        -- Reinit snapshot or transactional subscription (article level)
        if @publication_type = 0 or @publication_type = 1
        begin
            set @proc = @publisher + '.' + @publisher_db + '.dbo.sp_reinitsubscription'
            exec @retcode = @proc
                @publication = @publication,
                @article = @article,
                @subscriber = @subscriber,
                @destination_db = @subscriber_db
            -- Ignore failures, update status bit if successful
            if @retcode = 0
            begin
                -- Change status to 1 which means the alerts has been serviced
                update msdb..sysreplicationalerts set status = 1 where alert_id = @alert_id

                -- Raiserror that subscription was reinitialized
                if @failure_level = 0
                    -- 'Subscriber ''%s'' subscription to article ''%s'' in publication ''%s'' has been reinitialized after a synchronization failure.'
                    raiserror(20576, 10,-1, @subscriber, @article, @publication) 
                else if @failure_level  = 1
                    -- 'Subscriber ''%s'' subscription to article ''%s'' in publication ''%s'' has been reinitialized after a validation failure.'
                    raiserror(20572, 10,-1, @subscriber, @article, @publication) 
            end
            else -- failure
                set @return_value = 1
        end
/* Placeholder for Merge logic
        -- Reinit merge subscription (full publication)
        else if @publication_type = 3       
        begin
            set @proc = @publisher + '.' + @publisher_db + '.dbo.sp_reinitmergesubscription'
            exec @retcode = @proc
                @publication = @publication,
                @subscriber = @subscriber,
                @subscriber_db = @subscriber_db
            -- Ignore failures, update status bit if successful
            if @retcode = 0
            begin
                -- Change status to 1 which means the alerts has been serviced
                update msdb..sysreplicationalerts set status = 1 where alert_id = @alert_id

                -- Raiserror that subscription was reinitialized
                if @failure_level = 0
                    -- 'Subscriber ''%s'' subscription to publication ''%s'' has been reinitialized after a synchronization failure.'
                    raiserror(20576, 10,-1, @subscriber, @publication) 
                else if @failure_level  = 1
                    -- 'Subscriber ''%s'' subscription to publication ''%s'' has been reinitialized after a validation failure.'
                    raiserror(20572, 10,-1, @subscriber, @publication) 
            end
            else -- failure
                set @return_value = 1
        end
*/
        fetch hc into  @publisher, @publisher_db, @publication, @publication_type, @article, @subscriber, @subscriber_db, @alert_id
    end

    close hc
    deallocate hc

    -- Return a message stating no entries where found
    if @found = 0
    begin
        -- 'No entries were found in msdb..sysreplicationalerts.'
        raiserror(20577, 10,-1) 

        -- There is most likely a problem, set failure return value
        set @return_value = 1
    end

    return @return_value 
go
dump tran master with no_log
GO

raiserror('Creating procedure sp_add_datatype_mapping', 0,1)
go

-- Add a row into the "MSdatatype_mappings" table
create procedure sp_add_datatype_mapping (
    @dbms_name          sysname,
    @sql_type           sysname,
    @dest_type          sysname,
    @dest_prec          int,
    @dest_create_params int,
    @dest_nullable      bit
)
as
    set nocount on

    if @dbms_name is null
    BEGIN
        RAISERROR (14043, 16, -1, '@dbms_name')
        RETURN (1)
    END
    
    if @sql_type is null 
    BEGIN
        RAISERROR (14043, 16, -1, '@sql_type')
        RETURN (1)
    END

    if @dest_type is null
    BEGIN
        RAISERROR (14043, 16, -1, '@dest_type')
        RETURN (1)
    END

    if @dest_prec is null
    BEGIN
        RAISERROR (14043, 16, -1, '@dest_prec')
        RETURN (1)
    END

    if @dest_create_params is null
    BEGIN
        RAISERROR (14043, 16, -1, '@dest_create_params')
        RETURN (1)
    END

    if @dest_nullable is null
    BEGIN
        RAISERROR (14043, 16, -1, '@dest_nullable')
        RETURN (1)
    END
 

    insert into msdb..MSdatatype_mappings
    values (@dbms_name, @sql_type, @dest_type, @dest_prec, @dest_create_params, @dest_nullable)

    if @@error <> 0
        return(1)
GO


raiserror('Creating procedure sp_help_datatype_mapping', 0,1)
go
create procedure sp_help_datatype_mapping(
    @dbms_name          sysname,
    @sql_type           sysname = '%',
    @source_prec        int = NULL
)
as
    set nocount on
    
    if @source_prec is NULL
    begin
        select sql_type, dest_type, dest_prec, dest_create_params, dest_nullable
        from msdb..MSdatatype_mappings 
        where dbms_name = @dbms_name
        and sql_type like @sql_type
    end
    else
    begin
        select sql_type, dest_type, dest_prec, dest_create_params, dest_nullable
        from msdb..MSdatatype_mappings 
        where dbms_name = @dbms_name
        and sql_type like @sql_type
        and dest_prec = (select min(dest_prec)
                            from msdb..MSdatatype_mappings 
                            where dbms_name = @dbms_name
                            and sql_type like @sql_type
                            and dest_prec >= @source_prec
                        )
    end
GO

raiserror('Creating procedure sp_MSfix_6x_tasks', 0,1)
go
CREATE PROCEDURE sp_MSfix_6x_tasks (
	@publisher sysname = NULL
) AS

    SET NOCOUNT ON

    DECLARE @distributor sysname
    DECLARE @distproc nvarchar (255)
	declare @retcode int

	-- If @publisher is null redirect the call to distributor
	if @publisher is null
	begin
		/*
		** Get distribution server information for remote RPC
		** agent verification.
		*/
		EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT

		IF @@error <> 0 OR @retcode <> 0
		BEGIN
			RAISERROR (14071, 16, -1)
			RETURN (1)
		END

		/*
		** RPC distributor
		*/
		SELECT @distproc = RTRIM(@distributor) + '.master.dbo.sp_MSfix_6x_tasks'

		EXECUTE @retcode = @distproc
			@publisher = @@SERVERNAME
		IF @@ERROR <> 0 or @retcode <> 0
			return (1)
	end
	else
	begin

		declare @category_id int
		declare @category_name sysname
		declare @server sysname
		declare @databasename sysname
		declare @name sysname
		declare @distdb sysname
		declare @job_id uniqueidentifier
		declare @sSubsystem sysname

        -- Drop entry in systasks first.
        DECLARE hCtasks CURSOR LOCAL FAST_FORWARD FOR
            SELECT name FROM msdb.dbo.systasks_view st WHERE 
                
                -- drop distribution agents.
                (st.name LIKE @publisher + '_' + '%' + '_' + '%' AND 
                LOWER(subsystem) = 'distribution' AND
                server = @@SERVERNAME) OR
                                
                (LOWER(subsystem) = 'logreader' AND
                server = @publisher) OR 
                
                (LOWER(subsystem) = 'snapshot' AND
                server = @publisher) OR

                (st.name LIKE '%' + '_' + '%' + '_Cleanup' AND 
				st.command LIKE '%' + 'sp_replcleanup' + '%' AND
				LOWER(subsystem) = 'tsql')
            FOR READ ONLY

        OPEN hCtasks
        FETCH hCtasks INTO @name

        WHILE (@@fetch_status <> -1)
        BEGIN
            
            EXEC @retcode = msdb.dbo.sp_droptask @name = @name
            if @retcode <> 0 or @@error <> 0
                return(1)
            FETCH hCtasks INTO @name
        END

		-- Now spin through each old replication job and fixup categories names
		declare hcJobsToFix CURSOR LOCAL FAST_FORWARD for 
				select distinct j.job_id, j.name, s.subsystem, 
					s.server, s.database_name
					from msdb.dbo.sysjobs j left join msdb.dbo.sysjobsteps s
						on j.job_id = s.job_id
					where j.category_id = 0 and s.step_id = 1 and lower(s.subsystem) in ( 'snapshot', 'logreader', 'distribution' )
				for read only

		open hcJobsToFix 
		fetch hcJobsToFix into @job_id, @name, @sSubsystem,
			@server,@databasename

		while (@@fetch_status <> -1 )
		begin
			-- Note, have to make it a transaction, once the category_id is changed,
			-- the task will never be picked up again.
			begin tran 

				-- Get Distribution category name (assumes category_id = 10)
				select @category_id =
					case lower(@sSubsystem) 
						when 'snapshot' then 15
						when 'distribution' then 10
						when 'logReader' then 13
						else 0
					end

				select @category_name = name FROM msdb.dbo.syscategories where category_id = @category_id
				
				-- raiserror( 'Would update %s to category %d based on subsystem value %s', -1, 10, @nJobName, @iCategory, @sSubsystem )
				exec @retcode = msdb.dbo.sp_update_job @job_id = @job_id, 
					@category_name = @category_name
				if @retcode <> 0 or @@error <> 0
					goto UNDO


				-- Add the replication agent for monitoring
				SELECT @distdb = distribution_db from msdb..MSdistpublishers where UPPER(name) = UPPER(@server)
				IF (@category_id = 13) -- Logreader
				BEGIN
					SELECT @distproc = @distdb + '.dbo.sp_MSadd_logreader_agent'
					EXECUTE @retcode = @distproc
						@name = @name,
						@publisher = @server,
						@publisher_db = @databasename,
						@publication = '',  
						@local_job = 1,
						@job_existing = 1,
						@job_id = @job_id

					IF (@retcode <> 0 or @@error<>0)
						goto UNDO
				END
				ELSE 
				IF (@category_id = 15) -- Snapshot
				BEGIN
                    DECLARE @publication sysname

                    SELECT @publication = NULL
                    EXECUTE master.dbo.sp_MSget_publication_from_taskname
                                            @taskname = @name,
                                            @publisher = @server,
                                            @publisherdb = @databasename,
                                            @publication = @publication OUTPUT

                    IF (@publication IS NOT NULL )
                    BEGIN    
					    SELECT @distproc = @distdb + '.dbo.sp_MSadd_snapshot_agent'

					    EXECUTE @retcode = @distproc
						    @name = @name,
						    @publisher = @server,
						    @publisher_db = @databasename,
						    @publication = @publication,
						    @local_job = 1,
						    @job_existing = 1,
						    @snapshot_jobid = @job_id

					    IF (@retcode <> 0 or @@error<>0)
						    goto UNDO
				
					    SELECT @distproc = @distdb + '.dbo.sp_MSadd_publication'
					    EXECUTE @retcode = @distproc
						    @publisher = @server,
						    @publisher_db = @databasename,
						    @publication = @publication,
						    @publication_type = 0 -- Transactional
					    IF (@retcode <> 0 or @@error<>0)
						    goto UNDO
                    END
				END
			commit tran
			fetch hcJobsToFix into @job_id, @name, @sSubsystem,
				@server,@databasename
		end			
		close hcJobsToFix
		deallocate hcJobsToFix
	end
	return (0)
UNDO:
	if @@trancount <> 0
		rollback tran
	return (1)
GO

/*
** Add extended stored procedures for replication support.
*/
sp_addextendedproc  'sp_repldone', 'repldone extended procedure'
go

sp_addextendedproc  'sp_repltrans', 'repltrans extended procedure'
go

sp_addextendedproc  'sp_replcounters', 'replcounters extended procedure'
go

sp_addextendedproc  'sp_replcmds', 'replcmds extended procedure'
go

sp_addextendedproc  'sp_replflush', 'replflush extended procedure'
go

dump tran master with no_log
go

sp_addextendedproc  'sp_replpostcmd', 'replpostcmd extended procedure'
go

sp_addextendedproc  'sp_replincrementlsn', 'replincrementlsn extended procedure'
go

sp_addextendedproc  'sp_replupdateschema', 'replupdateschema extended procedure'
go

sp_addextendedproc  'sp_replsetoriginator', 'replsetoriginator extended procedure'
go

/*
** Add xp_enum_dsn extended procedure
*/
sp_addextendedproc 'xp_dsninfo','xpsql70.dll'
go
exec dbo.sp_MS_marksystemobject xp_dsninfo
go

/*
** Add xp_enum_dsn extended procedure
*/
sp_addextendedproc 'xp_enumdsn','xpsql70.dll'
go
exec dbo.sp_MS_marksystemobject xp_enumdsn
go

/*
** Add xp_oledbinfo extended procedure
*/
sp_addextendedproc 'xp_oledbinfo','xprepl.dll'
go
exec dbo.sp_MS_marksystemobject xp_oledbinfo
go

/*
** Add xp_repl_encrypt extended procedure
*/
sp_addextendedproc 'xp_repl_encrypt','xprepl.dll'
go
exec dbo.sp_MS_marksystemobject xp_repl_encrypt
go


dump tran master with no_log
go

grant execute on dbo.sp_addpublication_snapshot to public
go
grant execute on dbo.sp_MShelpobjectpublications to public
go
grant execute on dbo.sp_helpreplicationdb to public
go
grant execute on dbo.sp_enumdsn to public
go
grant execute on dbo.sp_helpsubscriberinfo to public
go
grant execute on dbo.sp_replica to public
go
grant execute on dbo.sp_distcounters to public
go
grant execute on dbo.sp_helpdistributor to public
go
grant execute on dbo.sp_helpdistributiondb to public
go
grant execute on dbo.sp_helpdistpublisher to public
go
grant execute on dbo.sp_replcounters to public
go
grant execute on dbo.sp_MShelp_distdb to public
go
grant execute on dbo.sp_grant_publication_access to public
go
grant execute on dbo.sp_revoke_publication_access to public
go
grant execute on dbo.sp_help_publication_access to public
go
grant execute on dbo.sp_check_publication_access to public
go
grant execute on dbo.sp_replsetoriginator to public
go

grant execute on dbo.sp_repldone to public
go
grant execute on dbo.sp_repltrans to public
go
grant execute on dbo.sp_replcounters to public
go
grant execute on dbo.sp_replcmds to public
go
grant execute on dbo.sp_replpostcmd to public
go
grant execute on dbo.sp_replincrementlsn to public
go


dump tran master with no_log
go



dump tran master with no_log
go
sp_configure 'allow updates',0
go
reconfigure with override
go

print ''
print 'Checking objects created by replcom.sql.'
go
--obsolete   exec dbo.sp_check_objects 'repl'
exec dbo.sp_MS_upd_sysobj_category 2  --set sysobjects.category | 2 based on crdate.
go

print ''
print 'replcom.sql completed successfully.'
go

dump tran master with no_log
go
checkpoint
go
-- - -----
